summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorChris Banes <chrisbanes@google.com>2015-02-23 12:30:13 +0000
committerChris Banes <chrisbanes@google.com>2015-02-27 08:56:04 +0000
commit9cc36ca1b520c06f882e84b909f3a2b75d303a06 (patch)
tree64778fc1ebedd614503fbea1e81a8dd1cf8f942b /core/java/android
parent1b4b87c2aec1ea5487e7279e92114bb1dca013b6 (diff)
downloadframeworks_base-9cc36ca1b520c06f882e84b909f3a2b75d303a06.zip
frameworks_base-9cc36ca1b520c06f882e84b909f3a2b75d303a06.tar.gz
frameworks_base-9cc36ca1b520c06f882e84b909f3a2b75d303a06.tar.bz2
MenuItem, navigation and overflow icon tinting
- iconTint and iconTintMode attrs for MenuItem, with associated setters. - navigationTint and navigationTintMode attrs for Toolbar with associated setters. - overlflowTint and overflowTintMode attrs for Toolbar with associated setters. BUG: 18126050 BUG: 19148351 BUG: 19305408 Change-Id: Ibd1fae7cdbc7a7c42809e52541fae5d8beb18e92
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/view/MenuInflater.java32
-rw-r--r--core/java/android/view/MenuItem.java24
-rw-r--r--core/java/android/widget/ActionMenuPresenter.java51
-rw-r--r--core/java/android/widget/ActionMenuView.java27
-rw-r--r--core/java/android/widget/Toolbar.java150
5 files changed, 280 insertions, 4 deletions
diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java
index 3492aa0..b49a59e 100644
--- a/core/java/android/view/MenuInflater.java
+++ b/core/java/android/view/MenuInflater.java
@@ -25,8 +25,11 @@ import android.annotation.MenuRes;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -334,6 +337,11 @@ public class MenuInflater {
private ActionProvider itemActionProvider;
+ private ColorStateList itemIconTintList;
+ private boolean itemIconTintListSet;
+ private PorterDuff.Mode itemIconTintMode;
+ private boolean itemIconTintModeSet;
+
private static final int defaultGroupId = NO_ID;
private static final int defaultItemId = NO_ID;
private static final int defaultItemCategory = 0;
@@ -424,6 +432,23 @@ public class MenuInflater {
itemActionProvider = null;
}
+ if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTint)) {
+ itemIconTintList = a.getColorStateList(
+ com.android.internal.R.styleable.MenuItem_iconTint);
+ itemIconTintListSet = true;
+ } else {
+ itemIconTintList = null;
+ itemIconTintListSet = false;
+ }
+ if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTintMode)) {
+ itemIconTintMode = Drawable.parseTintMode(
+ a.getInt(com.android.internal.R.styleable.MenuItem_iconTintMode, -1), null);
+ itemIconTintModeSet = true;
+ } else {
+ itemIconTintMode = null;
+ itemIconTintModeSet = false;
+ }
+
a.recycle();
itemAdded = false;
@@ -486,6 +511,13 @@ public class MenuInflater {
if (itemActionProvider != null) {
item.setActionProvider(itemActionProvider);
}
+
+ if (itemIconTintListSet) {
+ item.setIconTintList(itemIconTintList);
+ }
+ if (itemIconTintModeSet) {
+ item.setIconTintMode(itemIconTintMode);
+ }
}
public MenuItem addItem() {
diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java
index 9e8b97e..2948007 100644
--- a/core/java/android/view/MenuItem.java
+++ b/core/java/android/view/MenuItem.java
@@ -21,6 +21,8 @@ import android.annotation.LayoutRes;
import android.annotation.StringRes;
import android.app.Activity;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
@@ -599,4 +601,26 @@ public interface MenuItem {
* @return This menu item instance for call chaining
*/
public MenuItem setOnActionExpandListener(OnActionExpandListener listener);
+
+ /**
+ * Applies a tint to the icon drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link android.view.MenuItem#setIcon(android.graphics.drawable.Drawable)}
+ * will automatically mutate the drawable and apply the specified tint and tint mode.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public MenuItem setIconTintList(ColorStateList tint);
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setIconTintList(ColorStateList)} to the icon drawable. The default mode is {@link
+ * PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ * @return This menu item instance for call chaining
+ */
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode);
}
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index 94827dd..4fadc19 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -17,10 +17,10 @@
package android.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Matrix;
-import android.graphics.Rect;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -55,7 +55,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
implements ActionProvider.SubUiVisibilityListener {
private static final String TAG = "ActionMenuPresenter";
- private View mOverflowButton;
+ private OverflowMenuButton mOverflowButton;
private boolean mReserveOverflow;
private boolean mReserveOverflowSet;
private int mWidthLimit;
@@ -79,6 +79,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter
private OpenOverflowRunnable mPostedOpenRunnable;
private ActionMenuPopupCallback mPopupCallback;
+ private TintInfo mOverflowTintInfo;
+
final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
int mOpenSubMenuId;
@@ -113,6 +115,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
mOverflowButton = new OverflowMenuButton(mSystemContext);
final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
mOverflowButton.measure(spec, spec);
+ applyOverflowTint();
}
width -= mOverflowButton.getMeasuredWidth();
} else {
@@ -236,6 +239,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
if (hasOverflow) {
if (mOverflowButton == null) {
mOverflowButton = new OverflowMenuButton(mSystemContext);
+ applyOverflowTint();
}
ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
if (parent != mMenuView) {
@@ -550,6 +554,40 @@ public class ActionMenuPresenter extends BaseMenuPresenter
menuView.initialize(mMenu);
}
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintList = tint;
+ mOverflowTintInfo.mHasTintList = true;
+
+ applyOverflowTint();
+ }
+
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintMode = tintMode;
+ mOverflowTintInfo.mHasTintMode = true;
+
+ applyOverflowTint();
+ }
+
+ private void applyOverflowTint() {
+ final TintInfo tintInfo = mOverflowTintInfo;
+ if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) {
+ if (mOverflowButton != null) {
+ if (tintInfo.mHasTintList) {
+ mOverflowButton.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mOverflowButton.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
private static class SavedState implements Parcelable {
public int openSubMenuId;
@@ -774,4 +812,11 @@ public class ActionMenuPresenter extends BaseMenuPresenter
return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
}
}
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 403e4ac..9d3a5dc 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -16,7 +16,9 @@
package android.widget;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
+import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
@@ -546,6 +548,31 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
mReserveOverflow = reserveOverflow;
}
+ /**
+ * Applies a tint to the overflow drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mPresenter != null) {
+ mPresenter.setOverflowTintList(tint);
+ }
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setOverflowTintList(ColorStateList)} to the overflow drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ */
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mPresenter != null) {
+ mPresenter.setOverflowTintMode(tintMode);
+ }
+ }
+
@Override
protected LayoutParams generateDefaultLayoutParams() {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index c5325c4..9bc2aab 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -20,8 +20,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActionBar;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.TypedArray;
-import android.graphics.RectF;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -104,6 +105,9 @@ public class Toolbar extends ViewGroup {
private ImageButton mNavButtonView;
private ImageView mLogoView;
+ private TintInfo mOverflowTintInfo;
+ private TintInfo mNavTintInfo;
+
private Drawable mCollapseIcon;
private CharSequence mCollapseDescription;
private ImageButton mCollapseButtonView;
@@ -266,6 +270,21 @@ public class Toolbar extends ViewGroup {
if (!TextUtils.isEmpty(navDesc)) {
setNavigationContentDescription(navDesc);
}
+
+ if (a.hasValue(R.styleable.Toolbar_overflowTint)) {
+ setOverflowTintList(a.getColorStateList(R.styleable.Toolbar_overflowTint));
+ }
+ if (a.hasValue(R.styleable.Toolbar_overflowTintMode)) {
+ setOverflowTintMode(Drawable.parseTintMode(
+ a.getInt(R.styleable.Toolbar_overflowTintMode, -1), null));
+ }
+ if (a.hasValue(R.styleable.Toolbar_navigationTint)) {
+ setNavigationTintList(a.getColorStateList(R.styleable.Toolbar_navigationTint));
+ }
+ if (a.hasValue(R.styleable.Toolbar_navigationTintMode)) {
+ setNavigationTintMode(Drawable.parseTintMode(
+ a.getInt(R.styleable.Toolbar_navigationTintMode, -1), null));
+ }
a.recycle();
}
@@ -806,6 +825,91 @@ public class Toolbar extends ViewGroup {
}
/**
+ * Applies a tint to the icon drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link #setNavigationIcon(Drawable)} will automatically mutate
+ * the drawable and apply the specified tint and tint mode.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_navigationTint
+ */
+ public void setNavigationTintList(ColorStateList tint) {
+ if (mNavTintInfo == null) {
+ mNavTintInfo = new TintInfo();
+ }
+ mNavTintInfo.mTintList = tint;
+ mNavTintInfo.mHasTintList = true;
+
+ applyNavigationTint();
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setNavigationTintList(ColorStateList)} to the navigation drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_navigationTintMode
+ */
+ public void setNavigationTintMode(PorterDuff.Mode tintMode) {
+ if (mNavTintInfo == null) {
+ mNavTintInfo = new TintInfo();
+ }
+ mNavTintInfo.mTintMode = tintMode;
+ mNavTintInfo.mHasTintMode = true;
+
+ applyNavigationTint();
+ }
+
+ /**
+ * Applies a tint to the overflow drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_overflowTint
+ */
+ public void setOverflowTintList(ColorStateList tint) {
+ if (mMenuView != null) {
+ // If the menu view is available, directly set the tint
+ mMenuView.setOverflowTintList(tint);
+ } else {
+ // Otherwise we will record the value
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintList = tint;
+ mOverflowTintInfo.mHasTintList = true;
+ }
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by {@link
+ * #setOverflowTintList(ColorStateList)} to the overflow drawable.
+ * The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#Toolbar_overflowTintMode
+ */
+ public void setOverflowTintMode(PorterDuff.Mode tintMode) {
+ if (mMenuView != null) {
+ // If the menu view is available, directly set the tint mode
+ mMenuView.setOverflowTintMode(tintMode);
+ } else {
+ // Otherwise we will record the value
+ if (mOverflowTintInfo == null) {
+ mOverflowTintInfo = new TintInfo();
+ }
+ mOverflowTintInfo.mTintMode = tintMode;
+ mOverflowTintInfo.mHasTintMode = true;
+ }
+ }
+
+ /**
* Return the Menu shown in the toolbar.
*
* <p>Applications that wish to populate the toolbar's menu can do so from here. To use
@@ -841,6 +945,17 @@ public class Toolbar extends ViewGroup {
lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mMenuView.setLayoutParams(lp);
addSystemView(mMenuView);
+
+ if (mOverflowTintInfo != null) {
+ // If we have tint info for the overflow, set it on the menu view now
+ if (mOverflowTintInfo.mHasTintList) {
+ mMenuView.setOverflowTintList(mOverflowTintInfo.mTintList);
+ }
+ if (mOverflowTintInfo.mHasTintMode) {
+ mMenuView.setOverflowTintMode(mOverflowTintInfo.mTintMode);
+ }
+ mOverflowTintInfo = null;
+ }
}
}
@@ -994,6 +1109,7 @@ public class Toolbar extends ViewGroup {
final LayoutParams lp = generateDefaultLayoutParams();
lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
mNavButtonView.setLayoutParams(lp);
+ applyNavigationTint();
}
}
@@ -1012,6 +1128,7 @@ public class Toolbar extends ViewGroup {
collapseActionView();
}
});
+ applyNavigationTint();
}
}
@@ -1763,6 +1880,30 @@ public class Toolbar extends ViewGroup {
return mPopupContext;
}
+ private void applyNavigationTint() {
+ final TintInfo tintInfo = mNavTintInfo;
+ if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) {
+ if (mNavButtonView != null) {
+ if (tintInfo.mHasTintList) {
+ mNavButtonView.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mNavButtonView.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+
+ if (mCollapseButtonView != null) {
+ // We will use the same tint for the collapse button
+ if (tintInfo.mHasTintList) {
+ mCollapseButtonView.setImageTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mCollapseButtonView.setImageTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
/**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
@@ -1990,4 +2131,11 @@ public class Toolbar extends ViewGroup {
public void onRestoreInstanceState(Parcelable state) {
}
}
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}