Mholloway has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/382723 )

Change subject: Add color transition for page toolbar colors in light mode
......................................................................

Add color transition for page toolbar colors in light mode

In light mode, updates the page toolbar icons to white when a lead image
is present, then transitions them to black over the course of the on-
scroll animation.

Bug: T170304
Change-Id: Ib4e16380f657830ebc5f5ac575eaff46d986f060
---
M app/src/main/java/org/wikipedia/page/PageActivity.java
M app/src/main/java/org/wikipedia/page/PageFragment.java
A app/src/main/java/org/wikipedia/page/PageToolbarAnimationHandler.java
D app/src/main/java/org/wikipedia/page/PageToolbarHideHandler.java
M app/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
M app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
6 files changed, 183 insertions(+), 65 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/23/382723/1

diff --git a/app/src/main/java/org/wikipedia/page/PageActivity.java 
b/app/src/main/java/org/wikipedia/page/PageActivity.java
index 24f2d46..f638191 100644
--- a/app/src/main/java/org/wikipedia/page/PageActivity.java
+++ b/app/src/main/java/org/wikipedia/page/PageActivity.java
@@ -81,6 +81,7 @@
 import butterknife.Unbinder;
 
 import static org.wikipedia.settings.Prefs.isLinkPreviewEnabled;
+import static org.wikipedia.util.ResourceUtil.getThemedColor;
 import static org.wikipedia.util.UriUtil.visitInExternalBrowser;
 
 public class PageActivity extends BaseActivity implements 
PageFragment.Callback,
@@ -110,7 +111,7 @@
     private EventBusMethods busMethods;
     private ActionMode currentActionMode;
 
-    private PageToolbarHideHandler toolbarHideHandler;
+    private PageToolbarAnimationHandler toolbarAnimationHandler;
 
     private ExclusiveBottomSheetPresenter bottomSheetPresenter = new 
ExclusiveBottomSheetPresenter();
 
@@ -158,7 +159,9 @@
         clearActionBarTitle();
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
-        toolbarHideHandler = new PageToolbarHideHandler(toolbarContainerView);
+        toolbarAnimationHandler = new 
PageToolbarAnimationHandler(toolbarContainerView,
+                getThemedColor(this, R.attr.page_toolbar_icon_color));
+        
toolbarAnimationHandler.addMutableToolbarIcons(toolbar.getNavigationIcon(), 
toolbar.getOverflowIcon());
 
         boolean languageChanged = false;
         if (savedInstanceState != null) {
@@ -210,9 +213,11 @@
         MenuItem contentIssues = menu.findItem(R.id.menu_page_content_issues);
         MenuItem similarTitles = menu.findItem(R.id.menu_page_similar_titles);
         MenuItem themeChooserItem = 
menu.findItem(R.id.menu_page_font_and_theme);
+        MenuItem searchItem = menu.findItem(R.id.menu_page_search);
         MenuItem tabsItem = menu.findItem(R.id.menu_page_show_tabs);
 
         
tabsItem.setIcon(ResourceUtil.getTabListIcon(pageFragment.getTabCount()));
+        
toolbarAnimationHandler.addMutableToolbarMenuIcons(searchItem.getIcon(), 
tabsItem.getIcon());
 
         if (pageFragment.isLoading() || pageFragment.getErrorState()) {
             otherLangItem.setEnabled(false);
@@ -549,9 +554,12 @@
 
     @Override
     public void onPageInitWebView(@NonNull ObservableWebView webView) {
-        toolbarHideHandler.setScrollView(webView);
+        toolbarAnimationHandler.setScrollView(webView);
     }
 
+    // NOTE: This method is not called on every page load, but only from 
certain contexts, where the
+    // intent is to load a new page and put it on top of the current backstack.
+    // TODO: remove this from PageActivity 
(https://phabricator.wikimedia.org/T150797)
     @Override
     public void onPageLoadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry) {
         loadPage(title, entry);
@@ -642,17 +650,28 @@
 
     @Override
     public void onPageHideAllContent() {
-        toolbarHideHandler.setFadeEnabled(false);
+        toolbarAnimationHandler.setFadeEnabled(false);
     }
 
     @Override
     public void onPageSetToolbarFadeEnabled(boolean enabled) {
-        toolbarHideHandler.setFadeEnabled(enabled);
+        toolbarAnimationHandler.setFadeEnabled(enabled);
     }
 
     @Override
     public void onPageSetToolbarForceNoFace(boolean force) {
-        toolbarHideHandler.setForceNoFade(force);
+        toolbarAnimationHandler.setForceNoFade(force);
+    }
+
+    @Override
+    public void onPageBeginPageLoad() {
+        toolbarAnimationHandler.resetToolbarIconState();
+        toolbar.invalidate();
+    }
+
+    @Override
+    public void onPageLeadImageFound() {
+        toolbarAnimationHandler.leadImageFound();
     }
 
     @Override
diff --git a/app/src/main/java/org/wikipedia/page/PageFragment.java 
b/app/src/main/java/org/wikipedia/page/PageFragment.java
index 9f49922..43d0d2a 100755
--- a/app/src/main/java/org/wikipedia/page/PageFragment.java
+++ b/app/src/main/java/org/wikipedia/page/PageFragment.java
@@ -107,6 +107,7 @@
         void onPageShowBottomSheet(@NonNull BottomSheetDialog dialog);
         void onPageShowBottomSheet(@NonNull BottomSheetDialogFragment dialog);
         void onPageDismissBottomSheet();
+        void onPageBeginPageLoad();
         void onPageLoadPage(@NonNull PageTitle title, @NonNull HistoryEntry 
entry);
         void onPageInitWebView(@NonNull ObservableWebView v);
         void onPageShowLinkPreview(@NonNull PageTitle title, int source);
@@ -127,6 +128,7 @@
         void onPageHideAllContent();
         void onPageSetToolbarFadeEnabled(boolean enabled);
         void onPageSetToolbarForceNoFace(boolean force);
+        void onPageLeadImageFound();
     }
 
     public static final int TOC_ACTION_SHOW = 0;
@@ -676,6 +678,11 @@
 
         leadImagesHandler.hide();
 
+        if (callback() != null) {
+            // noinspection ConstantConditions
+            callback().onPageBeginPageLoad();
+        }
+
         model.setTitle(title);
         model.setTitleOriginal(title);
         model.setCurEntry(entry);
@@ -957,6 +964,12 @@
         }
     }
 
+    public void onLeadImageFound() {
+        if (callback() != null) {
+            callback().onPageLeadImageFound();
+        }
+    }
+
     PageInfo getPageInfo() {
         return pageInfo;
     }
diff --git 
a/app/src/main/java/org/wikipedia/page/PageToolbarAnimationHandler.java 
b/app/src/main/java/org/wikipedia/page/PageToolbarAnimationHandler.java
new file mode 100644
index 0000000..0c638a5
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/page/PageToolbarAnimationHandler.java
@@ -0,0 +1,136 @@
+package org.wikipedia.page;
+
+import android.animation.ArgbEvaluator;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.view.Gravity;
+import android.view.View;
+
+import org.wikipedia.WikipediaApp;
+import org.wikipedia.theme.Theme;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.wikipedia.util.DimenUtil.getDensityScalar;
+
+class PageToolbarAnimationHandler extends ViewHideHandler {
+    private static final int FULL_OPACITY = 255;
+    private static final int ANIMATION_HEIGHT = (int) (200 * 
getDensityScalar());
+
+    private boolean fadeEnabled;
+    private boolean forceNoFade;
+    private boolean leadImageFound;
+
+    @NonNull private ArgbEvaluator argbEvaluator = new ArgbEvaluator();
+    @NonNull private Drawable toolbarBackground;
+    @ColorInt private int iconDestColor;
+
+    @NonNull private Set<Drawable> toolbarIcons = new HashSet<>();
+
+    // HACK: Unlike the "native" toolbar navigation and overflow icons, the 
menu item icons
+    // displayed on the action bar are only accessible after 
Activity.onPrepareOptionsMenu() is
+    // called. OnPrepareOptionsMenu may be called several times in the course 
of loading a page; and
+    // the drawables returned from menuItem.getIcon() on subsequent calls 
referring to the same
+    // underlying item do not satisfy equals() such that de facto duplicates 
are excluded from the
+    // Set. For this reason, we'll hold the action menu items in a separate 
field and clear it
+    // manually on each page load in order to prevent the Set from growing 
without bound over the
+    // course of a session.
+    @NonNull private Set<Drawable> menuIcons = new HashSet<>();
+
+
+    PageToolbarAnimationHandler(@NonNull View hideableView, @ColorInt int 
iconDestColor) {
+        super(hideableView, Gravity.TOP);
+        this.toolbarBackground = hideableView.getBackground().mutate();
+        this.iconDestColor = iconDestColor;
+    }
+
+    @Override
+    protected void onScrolled(int oldScrollY, int scrollY) {
+        int opacity = calculateScrollOpacity(scrollY);
+        toolbarBackground.setAlpha(opacity);
+        updateToolbarIconTint(scrollY);
+    }
+
+    /**
+     * Whether to enable fading in/out of the search bar when near the top of 
the article.
+     * @param enabled True to enable fading, false otherwise.
+     */
+    void setFadeEnabled(boolean enabled) {
+        fadeEnabled = enabled;
+        update();
+    }
+
+    /**
+     * Whether to temporarily disable fading of the search bar, even if fading 
is enabled otherwise.
+     * May be used when displaying a temporary UI element that requires the 
search bar to be shown
+     * fully, e.g. when the ToC is pulled out.
+     * @param force True to temporarily disable fading, false otherwise.
+     */
+    void setForceNoFade(boolean force) {
+        forceNoFade = force;
+        update();
+    }
+
+    void leadImageFound() {
+        leadImageFound = true;
+        updateToolbarIconTint(0);
+    }
+
+    void resetToolbarIconState() {
+        leadImageFound = false;
+        menuIcons = new HashSet<>();
+    }
+
+    void addMutableToolbarIcons(Drawable... drawables) {
+        toolbarIcons.addAll(Arrays.asList(drawables));
+        updateToolbarIconTint(0);
+    }
+
+    void addMutableToolbarMenuIcons(Drawable... drawables) {
+        menuIcons.addAll(Arrays.asList(drawables));
+        updateToolbarIconTint(0);
+    }
+
+    private void updateToolbarIconTint(int scrollY) {
+        if (shouldUpdateToolbarIconTint()) {
+            int color = getIconTintForScrollY(scrollY);
+            for (Drawable icon : toolbarIcons) {
+                icon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
+            }
+            for (Drawable icon : menuIcons) {
+                icon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
+            }
+        }
+    }
+
+    /** @return Alpha value between 0 and 0xff. */
+    private int calculateScrollOpacity(int scrollY) {
+        int opacity = FULL_OPACITY;
+        if (fadeEnabled && !forceNoFade) {
+            opacity = scrollY * FULL_OPACITY / ANIMATION_HEIGHT;
+        }
+        opacity = Math.max(0, opacity);
+        opacity = Math.min(FULL_OPACITY, opacity);
+        return opacity;
+    }
+
+    /** @return A @ColorInt value between iconDestColor and Color.WHITE. */
+    @ColorInt
+    private int getIconTintForScrollY(int scrollY) {
+        float fraction = Math.min((float) scrollY / (float) ANIMATION_HEIGHT, 
1.0f);
+        return (Integer) argbEvaluator.evaluate(fraction, Color.WHITE, 
iconDestColor);
+    }
+
+    private boolean shouldUpdateToolbarIconTint() {
+        return leadImageFound && currentThemeIsLight();
+    }
+
+    private static boolean currentThemeIsLight() {
+        return WikipediaApp.getInstance().getCurrentTheme() == Theme.LIGHT;
+    }
+}
diff --git a/app/src/main/java/org/wikipedia/page/PageToolbarHideHandler.java 
b/app/src/main/java/org/wikipedia/page/PageToolbarHideHandler.java
deleted file mode 100644
index facc04b..0000000
--- a/app/src/main/java/org/wikipedia/page/PageToolbarHideHandler.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.wikipedia.page;
-
-import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.view.Gravity;
-import android.view.View;
-
-import org.wikipedia.util.DimenUtil;
-
-public class PageToolbarHideHandler extends ViewHideHandler {
-    private static final int FULL_OPACITY = 255;
-
-    private boolean fadeEnabled;
-    private boolean forceNoFade;
-    @NonNull private final Drawable toolbarBackground;
-
-    public PageToolbarHideHandler(@NonNull View hideableView) {
-        super(hideableView, Gravity.TOP);
-        toolbarBackground = hideableView.getBackground().mutate();
-    }
-
-    /**
-     * Whether to enable fading in/out of the search bar when near the top of 
the article.
-     * @param enabled True to enable fading, false otherwise.
-     */
-    public void setFadeEnabled(boolean enabled) {
-        fadeEnabled = enabled;
-        update();
-    }
-
-    /**
-     * Whether to temporarily disable fading of the search bar, even if fading 
is enabled otherwise.
-     * May be used when displaying a temporary UI element that requires the 
search bar to be shown
-     * fully, e.g. when the ToC is pulled out.
-     * @param force True to temporarily disable fading, false otherwise.
-     */
-    public void setForceNoFade(boolean force) {
-        forceNoFade = force;
-        update();
-    }
-
-    @Override
-    protected void onScrolled(int oldScrollY, int scrollY) {
-        int opacity = calculateScrollOpacity(scrollY);
-        toolbarBackground.setAlpha(opacity);
-    }
-
-    /** @return Alpha value between 0 and 0xff. */
-    private int calculateScrollOpacity(int scrollY) {
-        final int fadeHeight = 200;
-        int opacity = FULL_OPACITY;
-        if (fadeEnabled && !forceNoFade) {
-            opacity = scrollY * FULL_OPACITY / (int) (fadeHeight * 
DimenUtil.getDensityScalar());
-        }
-        opacity = Math.max(0, opacity);
-        opacity = Math.min(FULL_OPACITY, opacity);
-        return opacity;
-    }
-}
diff --git 
a/app/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java 
b/app/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
index 2ef7751..ae7b171 100755
--- a/app/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
+++ b/app/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
@@ -263,6 +263,11 @@
             public void onEditLeadSection() {
                 parentFragment.getEditHandler().startEditingSection(0, null);
             }
+
+            @Override
+            public void onLeadImageFound() {
+                parentFragment.onLeadImageFound();
+            }
         });
     }
 
diff --git 
a/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java 
b/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
index 2212ddb..f212f17 100644
--- a/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
+++ b/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
@@ -76,6 +76,7 @@
         void onDescriptionClicked();
         void onEditDescription();
         void onEditLeadSection();
+        void onLeadImageFound();
     }
 
     public PageHeaderView(Context context) {
@@ -133,6 +134,9 @@
         image.load(url);
         int height = url == null ? 0 : leadImageHeightForDevice();
         setMinimumHeight(height);
+        if (url != null && callback != null) {
+            callback.onLeadImageFound();
+        }
     }
 
     public void setAnimationPaused(boolean paused) {

-- 
To view, visit https://gerrit.wikimedia.org/r/382723
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib4e16380f657830ebc5f5ac575eaff46d986f060
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to