diff options
author | cyBerta <cyberta@riseup.net> | 2022-12-15 15:11:22 +0100 |
---|---|---|
committer | cyBerta <cyberta@riseup.net> | 2022-12-15 23:59:53 +0100 |
commit | e090b6dd60daca11603b36a197dfe5b05ecc3cb9 (patch) | |
tree | 2779e7f0e59cb659fa71eb6c3aee8d04aefa6949 | |
parent | bccc782a143692a1db01f4725cd94784aa99ca72 (diff) |
center and capitalize actionbar title, in Bitmask, center but not capitalize title in riseupvpn, allow to configure both properties on compile time in build.gradle
13 files changed, 266 insertions, 146 deletions
diff --git a/app/build.gradle b/app/build.gradle index 20d3eb0e..6c1bf394 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,6 +60,10 @@ android { // the version file contains the versionCode of the latest release buildConfigField "String", "version_file_url", '"https://dl.bitmask.net/client/android/versioncode.txt"' + // if center_actionbar_title is set to true, the actionbar title and subtitle will be centered, otherwise default + buildConfigField 'boolean', 'actionbar_center_title', 'true' + buildConfigField 'boolean', 'actionbar_capitalize_title', 'true' + //ignore the following configs, only used in custom flavor buildConfigField 'String', 'donation_url', 'null' buildConfigField "String", "customProviderUrl", '""' @@ -174,6 +178,12 @@ android { //The duration in days to trigger the donation reminder buildConfigField 'int', 'donation_reminder_duration', '7' + // ActionBar design + + // if center_actionbar_title is set to true, the actionbar title and subtitle will be centered, otherwise default + buildConfigField 'boolean', 'actionbar_center_title', 'true' + buildConfigField 'boolean', 'actionbar_capitalize_title', 'false' + // Build apks for each architecture, in addition to one 'fat' apk containing libraries for all all architectures // enable this if you're publishing in gplay ext { diff --git a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java index f56f2223..9225755e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java @@ -17,6 +17,7 @@ package se.leap.bitmaskclient.base; +import static androidx.appcompat.app.ActionBar.DISPLAY_SHOW_CUSTOM; import static se.leap.bitmaskclient.R.string.downloading_vpn_certificate_failed; import static se.leap.bitmaskclient.R.string.vpn_certificate_user_message; import static se.leap.bitmaskclient.base.models.Constants.ASK_TO_CANCEL_VPN; @@ -34,7 +35,6 @@ import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_LOG_IN; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_SWITCH_PROVIDER; import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.storeProviderInPreferences; -import static se.leap.bitmaskclient.base.utils.ViewHelper.isBrightColor; import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_VPN_PREPARE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORID; @@ -46,17 +46,14 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_TIMEOUT; import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.USER_MESSAGE; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.graphics.drawable.ColorDrawable; -import android.os.Build; import android.os.Bundle; import android.util.Log; -import android.view.Window; -import android.view.WindowManager; +import android.view.Gravity; -import androidx.annotation.ColorRes; -import androidx.annotation.StringRes; +import androidx.annotation.ColorInt; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; @@ -70,6 +67,7 @@ import org.json.JSONObject; import java.util.Observable; import java.util.Observer; +import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.fragments.EipFragment; import se.leap.bitmaskclient.base.fragments.ExcludeAppsFragment; @@ -81,7 +79,7 @@ import se.leap.bitmaskclient.base.fragments.SettingsFragment; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; import se.leap.bitmaskclient.base.utils.PreferenceHelper; -import se.leap.bitmaskclient.base.utils.ViewHelper; +import se.leap.bitmaskclient.base.views.ActionBarTitle; import se.leap.bitmaskclient.eip.EIP; import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.eip.EipSetupListener; @@ -103,8 +101,6 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, public final static String ACTION_SHOW_DIALOG_FRAGMENT = "action_show_dialog_fragment"; public final static String ACTION_SHOW_MOTD_FRAGMENT = "action_show_motd_fragment"; - private @ColorRes int actionBarTextColor = R.color.colorActionBarTitleFont; - /** * Fragment managing the behaviors, interactions and presentation of the navigation drawer. */ @@ -113,8 +109,7 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.a_main); - setSupportActionBar(findViewById(R.id.toolbar)); - + setupActionBar(); navigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer); @@ -143,7 +138,6 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, newFragment.setArguments(bundle); } fragmentManagerEnhanced.replace(R.id.main_container, newFragment, MainActivity.TAG); - hideActionBarSubTitle(); } else { super.onBackPressed(); } @@ -171,7 +165,6 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, } bundle.putParcelable(PROVIDER_KEY, provider); fragment.setArguments(bundle); - hideActionBarSubTitle(); showActionBar(); break; case ACTION_SHOW_MOTD_FRAGMENT: @@ -181,12 +174,10 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, motdBundle.putString(EXTRA_MOTD_MSG, intent.getStringExtra(EXTRA_MOTD_MSG)); } fragment.setArguments(motdBundle); - hideActionBarSubTitle(); hideActionBar(); break; case ACTION_SHOW_LOG_FRAGMENT: fragment = new LogFragment(); - setActionBarTitle(R.string.log_fragment_title); showActionBar(); break; case ACTION_SHOW_DIALOG_FRAGMENT: @@ -209,6 +200,31 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, } } + private void setupActionBar() { + setSupportActionBar(findViewById(R.id.toolbar)); + final ActionBar actionBar = getSupportActionBar(); + Context context = actionBar.getThemedContext(); + actionBar.setDisplayOptions(DISPLAY_SHOW_CUSTOM); + + ActionBarTitle actionBarTitle = new ActionBarTitle(context); + actionBarTitle.setTitleCaps(BuildConfig.actionbar_capitalize_title); + actionBarTitle.setTitle(getString(R.string.app_name)); + + @ColorInt int titleColor = ContextCompat.getColor(context, R.color.colorActionBarTitleFont); + actionBarTitle.setTitleTextColor(titleColor); + + actionBarTitle.setCentered(BuildConfig.actionbar_center_title); + if (BuildConfig.actionbar_center_title) { + ActionBar.LayoutParams params = new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, + ActionBar.LayoutParams.MATCH_PARENT, + Gravity.CENTER); + actionBar.setCustomView(actionBarTitle, params); + } else { + actionBar.setCustomView(actionBarTitle); + } + } + private void hideActionBar() { ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { @@ -223,53 +239,6 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, } } - private void hideActionBarSubTitle() { - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setSubtitle(null); - } - } - private void setActionBarTitle(@StringRes int stringId) { - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setSubtitle(stringId); - } - } - - public @ColorRes int getActionBarTitleColor() { - return actionBarTextColor; - } - - public void setDefaultActivityBarColor() { - setActivityBarColor(R.color.colorPrimary, R.color.colorPrimaryDark, R.color.colorActionBarTitleFont); - } - - public void setActivityBarColor(@ColorRes int primaryColor, @ColorRes int secondaryColor, @ColorRes int textColor) { - ActionBar bar = getSupportActionBar(); - if (bar == null) { - return; - } - int color = ContextCompat.getColor(this, secondaryColor); - bar.setBackgroundDrawable(new ColorDrawable(color)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = this.getWindow(); - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - window.setStatusBarColor(ContextCompat.getColor(this, primaryColor)); - } - - if (bar.getTitle() == null) { - return; - } - - if (textColor == 0) { - actionBarTextColor = isBrightColor(color) ? R.color.actionbar_connectivity_state_text_color_dark : R.color.actionbar_connectivity_state_text_color_light; - } else { - actionBarTextColor = textColor; - } - - ViewHelper.setActionBarTextColor(bar, actionBarTextColor); - } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -313,7 +282,6 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, fragment.setArguments(arguments); new FragmentManagerEnhanced(getSupportFragmentManager()) .replace(R.id.main_container, fragment, MainActivity.TAG); - hideActionBarSubTitle(); } @Override diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/AboutFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/AboutFragment.java index 646637b9..e92aa703 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/AboutFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/AboutFragment.java @@ -18,7 +18,7 @@ import se.leap.bitmaskclient.R; import static android.view.View.VISIBLE; import static se.leap.bitmaskclient.R.string.about_fragment_title; -import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarTitle; +import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarSubtitle; public class AboutFragment extends Fragment { @@ -36,7 +36,7 @@ public class AboutFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.f_about, container, false); unbinder = ButterKnife.bind(this, view); - setActionBarTitle(this, about_fragment_title); + setActionBarSubtitle(this, about_fragment_title); return view; } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java index 66f976f6..409efcf0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java @@ -75,6 +75,7 @@ import se.leap.bitmaskclient.base.MainActivity; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; import se.leap.bitmaskclient.base.utils.PreferenceHelper; +import se.leap.bitmaskclient.base.utils.ViewHelper; import se.leap.bitmaskclient.base.views.LocationButton; import se.leap.bitmaskclient.base.views.MainButton; import se.leap.bitmaskclient.databinding.FEipBinding; @@ -164,8 +165,6 @@ public class EipFragment extends Fragment implements Observer { } gatewaysManager = new GatewaysManager(getContext()); - - } @Override @@ -178,6 +177,7 @@ public class EipFragment extends Fragment implements Observer { mainDescription = binding.mainDescription; subDescription = binding.subDescription; stateView = binding.stateView; + ViewHelper.setActionBarTitle(this, R.string.app_name); eipStatus.addObserver(this); torStatusObservable.addObserver(this); @@ -256,10 +256,7 @@ public class EipFragment extends Fragment implements Observer { super.onDestroyView(); Log.d(TAG, "onDestroyView"); - Activity activity = getActivity(); - if (activity != null) { - ((MainActivity) activity).setDefaultActivityBarColor(); - } + ViewHelper.setDefaultActivityBarColor(getActivity()); eipStatus.deleteObserver(this); providerObservable.deleteObserver(this); torStatusObservable.deleteObserver(this); @@ -423,11 +420,7 @@ public class EipFragment extends Fragment implements Observer { } private void setActivityBarColor(@ColorRes int primaryColor, @ColorRes int secondaryColor) { - Activity activity = getActivity(); - if (activity == null) { - return; - } - ((MainActivity) getActivity()).setActivityBarColor(primaryColor, secondaryColor, R.color.actionbar_connectivity_state_text_color_dark); + ViewHelper.setActivityBarColor(getActivity(), primaryColor, secondaryColor, R.color.actionbar_connectivity_state_text_color_dark); } private void handleNewState() { diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java index 1574dbb0..98c2e438 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java @@ -312,7 +312,7 @@ public class ExcludeAppsFragment extends Fragment implements AdapterView.OnItemC mListView.setOnItemClickListener(this); mListView.setEmptyView(v.findViewById(R.id.loading_container)); - ViewHelper.setActionBarTitle(this, exclude_apps_fragment_title); + ViewHelper.setActionBarSubtitle(this, exclude_apps_fragment_title); new Thread(() -> mListAdapter.populateList(getActivity())).start(); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java index 00bd55ef..749ffd9f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java @@ -52,7 +52,6 @@ import se.leap.bitmaskclient.eip.GatewaysManager; import static android.content.Context.MODE_PRIVATE; import static android.view.View.GONE; import static android.view.View.VISIBLE; -import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4; import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN; import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT; import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_VPN_FRAGMENT; @@ -60,7 +59,7 @@ import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges; -import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarTitle; +import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarSubtitle; interface LocationListSelectionListener { void onLocationManuallySelected(Location location); @@ -109,7 +108,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca initRecyclerView(); initRecommendedLocationEntry(); initBridgesHint(view); - setActionBarTitle(this, R.string.gateway_selection_title); + setActionBarSubtitle(this, R.string.gateway_selection_title); } @Override diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java index 6f0f29ef..8f73595d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java @@ -5,6 +5,10 @@ package se.leap.bitmaskclient.base.fragments; +import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount; +import static se.leap.bitmaskclient.R.string.log_fragment_title; +import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarSubtitle; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; @@ -59,10 +63,6 @@ import de.blinkt.openvpn.core.VpnStatus.StateListener; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.models.Constants; -import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount; -import static se.leap.bitmaskclient.R.string.log_fragment_title; -import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarTitle; - public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { public static final String TAG = LogFragment.class.getSimpleName(); private static final String LOGTIMEFORMAT = "logtimeformat"; @@ -533,7 +533,7 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. if (mShowOptionsLayout) mOptionsLayout.setVisibility(View.VISIBLE); - setActionBarTitle(this, log_fragment_title); + setActionBarSubtitle(this, log_fragment_title); return v; } @@ -557,7 +557,6 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java index 5c4e891e..68435fec 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java @@ -38,9 +38,6 @@ import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; import android.os.Handler; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -48,15 +45,11 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.ColorRes; import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import androidx.appcompat.widget.ViewUtils; -import androidx.core.content.ContextCompat; import androidx.core.view.GravityCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.Fragment; @@ -70,7 +63,6 @@ import se.leap.bitmaskclient.base.FragmentManagerEnhanced; import se.leap.bitmaskclient.base.MainActivity; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; -import se.leap.bitmaskclient.base.utils.ViewHelper; import se.leap.bitmaskclient.base.views.IconSwitchEntry; import se.leap.bitmaskclient.base.views.IconTextEntry; import se.leap.bitmaskclient.eip.EipStatus; @@ -179,7 +171,6 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen this.drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); toolbar = this.drawerLayout.findViewById(R.id.toolbar); - setupActionBar(); setupEntries(); setupActionBarDrawerToggle(activity); @@ -240,7 +231,6 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen Bundle arguments = new Bundle(); arguments.putParcelable(PROVIDER_KEY, currentProvider); fragment.setArguments(arguments); - hideActionBarSubTitle(); fragmentManager.replace(R.id.main_container, fragment, MainActivity.TAG); closeDrawer(); }); @@ -355,15 +345,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen } } - private ActionBar setupActionBar() { - AppCompatActivity activity = (AppCompatActivity) getActivity(); - activity.setSupportActionBar(toolbar); - final ActionBar actionBar = activity.getSupportActionBar(); - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setHomeButtonEnabled(true); - actionBar.setDisplayShowTitleEnabled(true); - return actionBar; - } + @NonNull private void closeDrawerWithDelay() { @@ -425,14 +407,6 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen } @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (drawerLayout != null && isDrawerOpen()) { - showGlobalContextActionBar(); - } - super.onCreateOptionsMenu(menu, inflater); - } - - @Override public boolean onOptionsItemSelected(MenuItem item) { if (drawerToggle.onOptionsItemSelected(item)) { return true; @@ -446,33 +420,6 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen preferences.unregisterOnSharedPreferenceChangeListener(this); } - /** - * Per the navigation drawer design guidelines, updates the action bar to show the global app - * 'context', rather than just what's in the current screen. - */ - private void showGlobalContextActionBar() { - ActionBar actionBar = getActionBar(); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setTitle(R.string.app_name); - Activity activity = getActivity(); - if (activity == null) { - return; - } - @ColorRes int titleColor = ((MainActivity) activity).getActionBarTitleColor(); - ViewHelper.setActionBarTextColor(actionBar, titleColor); - } - - private ActionBar getActionBar() { - return ((AppCompatActivity) getActivity()).getSupportActionBar(); - } - - private void hideActionBarSubTitle() { - ActionBar actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setSubtitle(null); - } - } - public void refresh() { Provider currentProvider = ProviderObservable.getInstance().getCurrentProvider(); account.setText(currentProvider.getName()); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java index f7d20aa9..d5bbd2c5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java @@ -24,7 +24,7 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUseObfuscatio import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useObfuscationPinning; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useSnowflake; -import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarTitle; +import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarSubtitle; import android.app.AlertDialog; import android.content.Context; @@ -90,7 +90,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh initGatewayPinningEntry(view); initExperimentalTransportsEntry(view); initObfuscationPinningEntry(view); - setActionBarTitle(this, advanced_settings); + setActionBarSubtitle(this, advanced_settings); return view; } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java index bbd77c36..8f4d7862 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java @@ -1,26 +1,39 @@ package se.leap.bitmaskclient.base.utils; +import android.app.Activity; import android.app.Notification; import android.content.Context; import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Build; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; +import android.util.Log; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; import androidx.annotation.ColorRes; import androidx.annotation.DimenRes; import androidx.annotation.StringRes; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.AppCompatTextView; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.base.views.ActionBarTitle; + /** * Created by cyberta on 29.06.18. */ public class ViewHelper { + private static final String TAG = ViewHelper.class.getSimpleName(); + public static int convertDimensionToPx(Context context, @DimenRes int dimension) { return context.getResources().getDimensionPixelSize(dimension); } @@ -30,16 +43,81 @@ public class ViewHelper { * @param fragment * @param stringId */ + public static void setActionBarSubtitle(Fragment fragment, @StringRes int stringId) { + AppCompatActivity appCompatActivity = (AppCompatActivity) fragment.getActivity(); + if (appCompatActivity != null) { + ActionBar actionBar = appCompatActivity.getSupportActionBar(); + if (actionBar != null) { + View customView = actionBar.getCustomView(); + if (customView instanceof ActionBarTitle) { + ActionBarTitle actionBarTitle = (ActionBarTitle) customView; + actionBarTitle.setSubtitle(stringId); + actionBarTitle.showSubtitle(true); + } + } + } + } + + /** + * Sets the subtitle of an activities action bar. The activity needs to be an AppCompatActivity. + * @param fragment + * @param stringId + */ public static void setActionBarTitle(Fragment fragment, @StringRes int stringId) { AppCompatActivity appCompatActivity = (AppCompatActivity) fragment.getActivity(); if (appCompatActivity != null) { ActionBar actionBar = appCompatActivity.getSupportActionBar(); if (actionBar != null) { - actionBar.setSubtitle(stringId); + View customView = actionBar.getCustomView(); + if (customView instanceof ActionBarTitle) { + ActionBarTitle actionBarTitle = (ActionBarTitle) customView; + actionBarTitle.setTitle(stringId); + actionBarTitle.showSubtitle(false); + } else { + Log.e(TAG, "ActionBar has no custom action title!"); + } } } } + + public static void setDefaultActivityBarColor(Activity activity) { + setActivityBarColor(activity, R.color.colorPrimary, R.color.colorPrimaryDark, R.color.colorActionBarTitleFont); + } + + public static void setActivityBarColor(Activity activity, @ColorRes int primaryColor, @ColorRes int secondaryColor, @ColorRes int textColor) { + if (!(activity instanceof AppCompatActivity)) { + return; + } + + ActionBar bar = ((AppCompatActivity) activity).getSupportActionBar(); + if (bar == null) { + return; + } + int color = ContextCompat.getColor(activity, secondaryColor); + bar.setBackgroundDrawable(new ColorDrawable(color)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Window window = activity.getWindow(); + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(ContextCompat.getColor(activity, primaryColor)); + } + + int actionBarTextColor; + if (textColor == 0) { + actionBarTextColor = isBrightColor(color) ? R.color.actionbar_connectivity_state_text_color_dark : R.color.actionbar_connectivity_state_text_color_light; + } else { + actionBarTextColor = textColor; + } + + View customView = bar.getCustomView(); + if (customView instanceof ActionBarTitle) { + ActionBarTitle actionBarTitle = (ActionBarTitle) customView; + actionBarTitle.setTitleTextColor(ContextCompat.getColor(bar.getThemedContext(), actionBarTextColor)); + } + } + + public static boolean isBrightColor(int color) { if (android.R.color.transparent == color) return true; diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java b/app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java new file mode 100644 index 00000000..a151305e --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java @@ -0,0 +1,96 @@ +package se.leap.bitmaskclient.base.views; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.widget.RelativeLayout; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.appcompat.widget.AppCompatTextView; +import androidx.appcompat.widget.LinearLayoutCompat; + +import se.leap.bitmaskclient.databinding.VActionbarTitleBinding; + +public class ActionBarTitle extends LinearLayoutCompat { + private AppCompatTextView actionBarTitle; + private AppCompatTextView actionBarSubtitle; + private LinearLayoutCompat container; + + public ActionBarTitle(@NonNull Context context) { + super(context); + initLayout(context); + } + + public ActionBarTitle(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + initLayout(context); + } + + public ActionBarTitle(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initLayout(context); + } + + public void initLayout(Context context) { + VActionbarTitleBinding binding = VActionbarTitleBinding.inflate(LayoutInflater.from(context), this, true); + actionBarTitle = binding.actionBarTitle; + actionBarSubtitle = binding.actionBarSubtitle; + container = binding.actionBarTitleContainer; + } + + public void setTitle(CharSequence text) { + actionBarTitle.setText(text); + } + + public void setTitleCaps(boolean caps) { + actionBarTitle.setAllCaps(caps); + } + + public void setSubtitle(CharSequence text) { + actionBarSubtitle.setText(text); + } + + public void setTitle(@StringRes int resId) { + actionBarTitle.setText(resId); + } + + public void setSubtitle(@StringRes int resId) { + actionBarSubtitle.setText(resId); + } + + public void setTitleTextColor(@ColorInt int color) { + actionBarTitle.setTextColor(color); + } + + public void setSubtitleTextColor(@ColorInt int color) { + actionBarSubtitle.setTextColor(color); + } + + public void showSubtitle(boolean show) { + actionBarSubtitle.setVisibility(show ? VISIBLE : GONE); + } + + public void setCentered(boolean centered) { + LayoutParams titleLayoutParams = (LayoutParams) actionBarTitle.getLayoutParams(); + LayoutParams subtitleLayoutParams = (LayoutParams) actionBarSubtitle.getLayoutParams(); + LayoutParams containerLayoutParams = (LayoutParams) container.getLayoutParams(); + if (centered) { + titleLayoutParams.gravity = Gravity.CENTER; + subtitleLayoutParams.gravity = Gravity.CENTER; + containerLayoutParams.gravity = Gravity.CENTER; + } else { + titleLayoutParams.gravity = Gravity.NO_GRAVITY; + subtitleLayoutParams.gravity = Gravity.NO_GRAVITY; + containerLayoutParams.gravity = Gravity.NO_GRAVITY; + } + actionBarTitle.setLayoutParams(titleLayoutParams); + actionBarSubtitle.setLayoutParams(subtitleLayoutParams); + container.setLayoutParams(containerLayoutParams); + + + } +} diff --git a/app/src/main/res/layout/a_main.xml b/app/src/main/res/layout/a_main.xml index 92e0a3c0..927217f4 100644 --- a/app/src/main/res/layout/a_main.xml +++ b/app/src/main/res/layout/a_main.xml @@ -22,8 +22,6 @@ android:minHeight="?attr/actionBarSize" android:layout_width="match_parent" android:layout_height="wrap_content" - app:titleTextColor="@color/colorActionBarTitleFont" - app:subtitleTextColor="@color/colorActionBarSubtitleFont" android:background="?attr/colorPrimary"> </androidx.appcompat.widget.Toolbar> diff --git a/app/src/main/res/layout/v_actionbar_title.xml b/app/src/main/res/layout/v_actionbar_title.xml new file mode 100644 index 00000000..1985ef21 --- /dev/null +++ b/app/src/main/res/layout/v_actionbar_title.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> + +<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/action_bar_title_container" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical"> + + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/action_bar_title" + android:layout_width="wrap_content" + tools:text="Bitmask" + android:layout_height="wrap_content" + android:ellipsize="end" + android:maxLines="1" + android:textStyle="normal" + android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title" + /> + + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/action_bar_subtitle" + android:layout_width="wrap_content" + tools:text="Advanced Settings" + android:layout_height="wrap_content" + android:ellipsize="end" + android:maxLines="1" + android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" + android:textColor="@color/colorActionBarSubtitleFont" + /> + +</androidx.appcompat.widget.LinearLayoutCompat> |