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