Bug 1332546 - Refactory ActionBar by extracting methods to another class draft
authorJulian_Chu <walkingice0204@gmail.com>
Fri, 03 Mar 2017 13:02:16 +0800
changeset 499669 46fed2d74416ae47dd2f0faecb91e98d97641003
parent 497875 6d38ad302429c98115c354d643e81987ecec5d3c
child 499670 e49e29f0d0dc6dc4ef59656066f2e184113ed25b
push id49471
push userbmo:walkingice0204@gmail.com
push dateThu, 16 Mar 2017 02:41:34 +0000
bugs1332546
milestone55.0a1
Bug 1332546 - Refactory ActionBar by extracting methods to another class ActionBar of CustomTabsActivity is getting complicated. There will be more components in ActionBar, such as Site-identity-icon. Move some action-bar related view code to another class. MozReview-Commit-ID: I5sOSCQKnlv
mobile/android/base/java/org/mozilla/gecko/customtabs/ActionBarPresenter.java
mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
mobile/android/base/moz.build
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/ActionBarPresenter.java
@@ -0,0 +1,90 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.customtabs;
+
+import android.graphics.drawable.ColorDrawable;
+import android.os.Build;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.util.ColorUtil;
+
+import java.lang.reflect.Field;
+
+/**
+ * This class is used to maintain appearance of ActionBar of CustomTabsActivity, includes background
+ * color, custom-view and so on.
+ */
+public class ActionBarPresenter {
+
+    private static final String LOGTAG = "CustomTabsActionBar";
+    private final ActionBar mActionBar;
+    private boolean useDomainTitle = true;
+
+    ActionBarPresenter(@NonNull final ActionBar actionBar, @NonNull Toolbar toolbar) {
+        mActionBar = actionBar;
+        initActionBar(toolbar);
+    }
+
+    private void initActionBar(@NonNull final Toolbar toolbar) {
+        try {
+            // Since we don't create the Toolbar's TextView ourselves, this seems
+            // to be the only way of changing the ellipsize setting.
+            final Field f = toolbar.getClass().getDeclaredField("mTitleTextView");
+            f.setAccessible(true);
+            final TextView textView = (TextView) f.get(toolbar);
+            textView.setEllipsize(TextUtils.TruncateAt.START);
+        } catch (Exception e) {
+            // If we can't ellipsize at the start of the title, we shouldn't display the host
+            // so as to avoid displaying a misleadingly truncated host.
+            Log.w(LOGTAG, "Failed to get Toolbar TextView, using default title.");
+            useDomainTitle = false;
+        }
+    }
+
+    /**
+     * Update appearance of ActionBar, includes its Title.
+     *
+     * @param title A string to be used as Title in Actionbar
+     */
+    @UiThread
+    public void update(@Nullable final String title) {
+        if (useDomainTitle || TextUtils.isEmpty(title)) {
+            mActionBar.setTitle(AppConstants.MOZ_APP_BASENAME);
+        } else {
+            mActionBar.setTitle(title);
+        }
+    }
+
+    /**
+     * Set background color to ActionBar, as well as Status bar.
+     *
+     * @param color  the color to apply to ActionBar
+     * @param window Window instance for changing color status bar, or null if won't change it.
+     */
+    @UiThread
+    public void setBackgroundColor(@ColorInt final int color,
+                                   @Nullable final Window window) {
+        mActionBar.setBackgroundDrawable(new ColorDrawable(color));
+
+        if (window != null) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+                window.setStatusBarColor(ColorUtil.darken(color, 0.25));
+            }
+        }
+    }
+}
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -8,62 +8,56 @@ package org.mozilla.gecko.customtabs;
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.BitmapDrawable;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.annotation.StyleRes;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.util.SparseArrayCompat;
 import android.support.v4.view.MenuItemCompat;
 import android.support.v7.app.ActionBar;
 import android.support.v7.widget.Toolbar;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
-import android.view.Window;
-import android.view.WindowManager;
 import android.widget.ImageButton;
-import android.widget.TextView;
 
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
 import org.mozilla.gecko.menu.GeckoMenu;
 import org.mozilla.gecko.menu.GeckoMenuInflater;
 import org.mozilla.gecko.util.ColorUtil;
 import org.mozilla.gecko.widget.GeckoPopupMenu;
 
-import java.lang.reflect.Field;
 import java.util.List;
 
 import static android.support.customtabs.CustomTabsIntent.EXTRA_TOOLBAR_COLOR;
 
 public class CustomTabsActivity extends GeckoApp implements Tabs.OnTabsChangedListener {
     private static final String LOGTAG = "CustomTabsActivity";
     private static final String SAVED_TOOLBAR_COLOR = "SavedToolbarColor";
     private static final String SAVED_TOOLBAR_TITLE = "SavedToolbarTitle";
     private static final int NO_COLOR = -1;
     private final SparseArrayCompat<PendingIntent> menuItemsIntent = new SparseArrayCompat<>();
-    private ActionBar actionBar;
     private GeckoPopupMenu popupMenu;
     private int tabId = -1;
-    private boolean useDomainTitle = true;
+    private ActionBarPresenter actionBarPresenter;
     private int toolbarColor;
     private String toolbarTitle;
     // A state to indicate whether this activity is finishing with customize animation
     private boolean usingCustomAnimation = false;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -73,44 +67,25 @@ public class CustomTabsActivity extends 
             toolbarTitle = savedInstanceState.getString(SAVED_TOOLBAR_TITLE, AppConstants.MOZ_APP_BASENAME);
         } else {
             toolbarColor = getIntent().getIntExtra(EXTRA_TOOLBAR_COLOR, NO_COLOR);
             toolbarTitle = AppConstants.MOZ_APP_BASENAME;
         }
 
         setThemeFromToolbarColor();
 
-        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
-        updateActionBarWithToolbar(toolbar);
-        try {
-            // Since we don't create the Toolbar's TextView ourselves, this seems
-            // to be the only way of changing the ellipsize setting.
-            Field f = toolbar.getClass().getDeclaredField("mTitleTextView");
-            f.setAccessible(true);
-            TextView textView = (TextView) f.get(toolbar);
-            textView.setEllipsize(TextUtils.TruncateAt.START);
-        } catch (Exception e) {
-            // If we can't ellipsize at the start of the title, we shouldn't display the host
-            // so as to avoid displaying a misleadingly truncated host.
-            Log.w(LOGTAG, "Failed to get Toolbar TextView, using default title.");
-            useDomainTitle = false;
-        }
-        actionBar = getSupportActionBar();
-        actionBar.setTitle(toolbarTitle);
-        updateToolbarColor(toolbar);
+        final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        setSupportActionBar(toolbar);
+        final ActionBar actionBar = getSupportActionBar();
+        actionBar.setDisplayHomeAsUpEnabled(true);
+        bindNavigationCallback(toolbar);
 
-        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                final Tabs tabs = Tabs.getInstance();
-                final Tab tab = tabs.getSelectedTab();
-                tabs.closeTab(tab);
-                finish();
-            }
-        });
+        actionBarPresenter = new ActionBarPresenter(actionBar, toolbar);
+        actionBarPresenter.setBackgroundColor(toolbarColor, getWindow());
+        actionBarPresenter.update(toolbarTitle);
 
         Tabs.registerOnTabsChangedListener(this);
     }
 
     private void setThemeFromToolbarColor() {
         // default theme, regardless AndroidManifest.
         @StyleRes int styleRes = R.style.GeckoCustomTabs;
 
@@ -182,22 +157,22 @@ public class CustomTabsActivity extends 
 
         if (msg == Tabs.TabEvents.LOCATION_CHANGE) {
             tabId = tab.getId();
             final Uri uri = Uri.parse(tab.getURL());
             String title = null;
             if (uri != null) {
                 title = uri.getHost();
             }
-            if (!useDomainTitle || title == null || title.isEmpty()) {
+            if (title == null || title.isEmpty()) {
                 toolbarTitle = AppConstants.MOZ_APP_BASENAME;
             } else {
                 toolbarTitle = title;
             }
-            actionBar.setTitle(toolbarTitle);
+            actionBarPresenter.update(toolbarTitle);
         }
 
         updateMenuItemForward();
     }
 
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
@@ -301,36 +276,26 @@ public class CustomTabsActivity extends 
                 IntentUtil.getActionButtonDescription(intent));
         Bitmap bitmap = IntentUtil.getActionButtonIcon(intent);
         item.setIcon(new BitmapDrawable(getResources(), bitmap));
         MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
 
         return item;
     }
 
-    private void updateActionBarWithToolbar(final Toolbar toolbar) {
-        setSupportActionBar(toolbar);
-        final ActionBar ab = getSupportActionBar();
-        if (ab != null) {
-            ab.setDisplayHomeAsUpEnabled(true);
-        }
-    }
-
-    private void updateToolbarColor(final Toolbar toolbar) {
-        if (toolbarColor == NO_COLOR) {
-            return;
-        }
-
-        toolbar.setBackgroundColor(toolbarColor);
-
-        final Window window = getWindow();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
-            window.setStatusBarColor(ColorUtil.darken(toolbarColor, 0.25));
-        }
+    private void bindNavigationCallback(@NonNull final Toolbar toolbar) {
+        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                final Tabs tabs = Tabs.getInstance();
+                final Tab tab = tabs.getSelectedTab();
+                tabs.closeTab(tab);
+                finish();
+            }
+        });
     }
 
     private void performPendingIntent(@NonNull PendingIntent pendingIntent) {
         // bug 1337771: If intent-creator haven't set data url, call send() directly won't work.
         final Intent additional = new Intent();
         final Tab tab = Tabs.getInstance().getSelectedTab();
         additional.setData(Uri.parse(tab.getURL()));
         try {
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -350,16 +350,17 @@ gbjar.sources += ['java/org/mozilla/geck
     'animation/ViewHelper.java',
     'ANRReporter.java',
     'BootReceiver.java',
     'BrowserApp.java',
     'BrowserLocaleManager.java',
     'cleanup/FileCleanupController.java',
     'cleanup/FileCleanupService.java',
     'CustomEditText.java',
+    'customtabs/ActionBarPresenter.java',
     'customtabs/CustomTabsActivity.java',
     'customtabs/GeckoCustomTabsService.java',
     'customtabs/IntentUtil.java',
     'DataReportingNotification.java',
     'db/AbstractPerProfileDatabaseProvider.java',
     'db/AbstractTransactionalProvider.java',
     'db/BaseTable.java',
     'db/BrowserDatabaseHelper.java',