am 60d5509d: Merge "Tidy up styling and tinting in NavigationView" into lmp-mr1-ub-dev
* commit '60d5509d4ce055532645a889d29f4201e6bc4512':
Tidy up styling and tinting in NavigationView
diff --git a/design/api/current.txt b/design/api/current.txt
index 94e0f9c..e7c86a0 100644
--- a/design/api/current.txt
+++ b/design/api/current.txt
@@ -156,14 +156,17 @@
ctor public NavigationView(android.content.Context, android.util.AttributeSet);
ctor public NavigationView(android.content.Context, android.util.AttributeSet, int);
method public void addHeaderView(android.view.View);
- method public int getItemBackgroundResource();
- method public android.content.res.ColorStateList getItemTintList();
+ method public android.graphics.drawable.Drawable getItemBackground();
+ method public android.content.res.ColorStateList getItemIconTintList();
+ method public android.content.res.ColorStateList getItemTextColor();
method public android.view.Menu getMenu();
method public android.view.View inflateHeaderView(int);
method public void inflateMenu(int);
method public void removeHeaderView(android.view.View);
+ method public void setItemBackground(android.graphics.drawable.Drawable);
method public void setItemBackgroundResource(int);
- method public void setItemTintList(android.content.res.ColorStateList);
+ method public void setItemIconTintList(android.content.res.ColorStateList);
+ method public void setItemTextColor(android.content.res.ColorStateList);
method public void setNavigationItemSelectedListener(android.support.design.widget.NavigationView.OnNavigationItemSelectedListener);
}
diff --git a/design/res/values/attrs.xml b/design/res/values/attrs.xml
index 2c34a9b..a090d88 100644
--- a/design/res/values/attrs.xml
+++ b/design/res/values/attrs.xml
@@ -46,7 +46,8 @@
<attr name="elevation"/>
<!-- The menu resource to inflate and populate items from. -->
<attr name="menu" format="reference"/>
- <attr name="itemTint" format="color|reference"/>
+ <attr name="itemIconTint" format="color"/>
+ <attr name="itemTextColor" format="color"/>
<attr name="itemBackground" format="reference"/>
<!-- Layout resource to inflate as the header -->
<attr name="headerLayout" format="reference"/>
diff --git a/design/src/android/support/design/internal/NavigationMenuItemView.java b/design/src/android/support/design/internal/NavigationMenuItemView.java
index 0db8f62..ba89776 100644
--- a/design/src/android/support/design/internal/NavigationMenuItemView.java
+++ b/design/src/android/support/design/internal/NavigationMenuItemView.java
@@ -29,7 +29,6 @@
import android.support.v7.internal.view.menu.MenuView;
import android.util.AttributeSet;
import android.util.TypedValue;
-import android.view.View;
import android.widget.TextView;
/**
@@ -39,13 +38,9 @@
private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
- private static final int[] DISABLED_STATE_SET = {-android.R.attr.state_enabled};
-
private int mIconSize;
-
private MenuItemImpl mItemData;
-
- private ColorStateList mTintList;
+ private ColorStateList mIconTintList;
public NavigationMenuItemView(Context context) {
this(context, null);
@@ -64,50 +59,22 @@
public void initialize(MenuItemImpl itemData, int menuType) {
mItemData = itemData;
- setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
+ setVisibility(itemData.isVisible() ? VISIBLE : GONE);
- if (mTintList == null && (itemData.isChecked() || !itemData.isEnabled())) {
- mTintList = createDefaultTintList();
- setTextColor(mTintList);
- }
if (getBackground() == null) {
setBackgroundDrawable(createDefaultBackground());
}
setCheckable(itemData.isCheckable());
setChecked(itemData.isChecked());
+ setEnabled(itemData.isEnabled());
setTitle(itemData.getTitle());
setIcon(itemData.getIcon());
- setEnabled(itemData.isEnabled());
- }
-
- private ColorStateList createDefaultTintList() {
- TypedValue value = new TypedValue();
- if (!getContext().getTheme()
- .resolveAttribute(android.R.attr.textColorPrimary, value, true)) {
- return null;
- }
- ColorStateList base = getResources().getColorStateList(value.resourceId);
- if (!getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true)) {
- return null;
- }
- int colorPrimary = value.data;
- int defaultColor = base.getDefaultColor();
- return new ColorStateList(new int[][]{
- DISABLED_STATE_SET,
- CHECKED_STATE_SET,
- EMPTY_STATE_SET
- }, new int[]{
- base.getColorForState(DISABLED_STATE_SET, defaultColor),
- colorPrimary,
- defaultColor
- });
}
private StateListDrawable createDefaultBackground() {
TypedValue value = new TypedValue();
- if (getContext().getTheme()
- .resolveAttribute(R.attr.colorControlHighlight, value, true)) {
+ if (getContext().getTheme().resolveAttribute(R.attr.colorControlHighlight, value, true)) {
StateListDrawable drawable = new StateListDrawable();
drawable.addState(CHECKED_STATE_SET, new ColorDrawable(value.data));
drawable.addState(EMPTY_STATE_SET, new ColorDrawable(Color.TRANSPARENT));
@@ -128,9 +95,7 @@
@Override
public void setCheckable(boolean checkable) {
- if (checkable && mTintList != null) {
- setTextColor(mTintList);
- }
+ refreshDrawableState();
}
@Override
@@ -146,13 +111,9 @@
public void setIcon(Drawable icon) {
if (icon != null) {
icon = DrawableCompat.wrap(icon);
- icon.setBounds(0, 0, mIconSize, mIconSize);
icon = icon.mutate();
- if (mItemData.isChecked() || !mItemData.isEnabled()) {
- DrawableCompat.setTintList(icon, mTintList);
- } else {
- DrawableCompat.setTintList(icon, null);
- }
+ icon.setBounds(0, 0, mIconSize, mIconSize);
+ DrawableCompat.setTintList(icon, mIconTintList);
}
TextViewCompat.setCompoundDrawablesRelative(this, icon, null, null, null);
}
@@ -169,19 +130,18 @@
@Override
protected int[] onCreateDrawableState(int extraSpace) {
- if (mItemData != null && mItemData.isChecked()) {
- return mergeDrawableStates(super.onCreateDrawableState(extraSpace + 1),
- CHECKED_STATE_SET);
- } else {
- return super.onCreateDrawableState(extraSpace);
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+ if (mItemData != null && mItemData.isCheckable() && mItemData.isChecked()) {
+ mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
+ return drawableState;
}
- public void setTintList(ColorStateList tintList) {
- mTintList = tintList;
- if (tintList != null) {
- setTextColor(tintList);
+ void setIconTintList(ColorStateList tintList) {
+ mIconTintList = tintList;
+ if (mItemData != null) {
+ // Update the icon so that the tint takes effect
+ setIcon(mItemData.getIcon());
}
}
-
}
diff --git a/design/src/android/support/design/internal/NavigationMenuPresenter.java b/design/src/android/support/design/internal/NavigationMenuPresenter.java
index 6aad1e5..e784bd5 100644
--- a/design/src/android/support/design/internal/NavigationMenuPresenter.java
+++ b/design/src/android/support/design/internal/NavigationMenuPresenter.java
@@ -20,9 +20,9 @@
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
-import android.support.annotation.DrawableRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -62,8 +62,9 @@
private NavigationMenuAdapter mAdapter;
private LayoutInflater mLayoutInflater;
- private ColorStateList mItemTintList;
- private int mItemBackgroundResource;
+ private ColorStateList mTextColor;
+ private ColorStateList mIconTintList;
+ private Drawable mItemBackground;
/**
* Padding to be inserted at the top of the list to avoid the first menu item
@@ -200,20 +201,28 @@
@Nullable
public ColorStateList getItemTintList() {
- return mItemTintList;
+ return mIconTintList;
}
- public void setItemTintList(@Nullable ColorStateList itemTintList) {
- mItemTintList = itemTintList;
+ public void setItemIconTintList(@Nullable ColorStateList tint) {
+ mIconTintList = tint;
}
- @DrawableRes
- public int getItemBackgroundResource() {
- return mItemBackgroundResource;
+ @Nullable
+ public ColorStateList getItemTextColor() {
+ return mTextColor;
}
- public void setItemBackgroundResource(@DrawableRes int itemBackgroundResource) {
- mItemBackgroundResource = itemBackgroundResource;
+ public void setItemTextColor(@Nullable ColorStateList textColor) {
+ mTextColor = textColor;
+ }
+
+ public Drawable getItemBackground() {
+ return mItemBackground;
+ }
+
+ public void setItemBackground(Drawable itemBackground) {
+ mItemBackground = itemBackground;
}
private class NavigationMenuAdapter extends BaseAdapter {
@@ -271,8 +280,9 @@
parent, false);
}
NavigationMenuItemView itemView = (NavigationMenuItemView) convertView;
- itemView.setTintList(mItemTintList);
- itemView.setBackgroundResource(mItemBackgroundResource);
+ itemView.setIconTintList(mIconTintList);
+ itemView.setTextColor(mTextColor);
+ itemView.setBackground(mItemBackground);
itemView.initialize(item.getMenuItem(), 0);
break;
case VIEW_TYPE_SUBHEADER:
diff --git a/design/src/android/support/design/widget/NavigationView.java b/design/src/android/support/design/widget/NavigationView.java
index 5ef279d..02dfa3c 100644
--- a/design/src/android/support/design/widget/NavigationView.java
+++ b/design/src/android/support/design/widget/NavigationView.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,10 +30,12 @@
import android.support.design.R;
import android.support.design.internal.NavigationMenuPresenter;
import android.support.design.internal.ScrimInsetsFrameLayout;
+import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.internal.view.SupportMenuInflater;
import android.support.v7.internal.view.menu.MenuBuilder;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -64,6 +67,9 @@
*/
public class NavigationView extends ScrimInsetsFrameLayout {
+ private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
+ private static final int[] DISABLED_STATE_SET = {-android.R.attr.state_enabled};
+
private static final int PRESENTER_NAVIGATION_VIEW_ID = 1;
private final MenuBuilder mMenu;
@@ -104,11 +110,21 @@
mMaxWidth = a.getDimensionPixelSize(R.styleable.NavigationView_android_maxWidth, 0);
- final ColorStateList itemTintList =
- a.getColorStateList(R.styleable.NavigationView_itemTint);
+ final ColorStateList itemIconTint;
+ if (a.hasValue(R.styleable.NavigationView_itemIconTint)) {
+ itemIconTint = a.getColorStateList(R.styleable.NavigationView_itemIconTint);
+ } else {
+ itemIconTint = createDefaultColorStateList(android.R.attr.textColorSecondary);
+ }
- final int itemBackgroundResource =
- a.getResourceId(R.styleable.NavigationView_itemBackground, 0);
+ final ColorStateList itemTextColor;
+ if (a.hasValue(R.styleable.NavigationView_itemTextColor)) {
+ itemTextColor = a.getColorStateList(R.styleable.NavigationView_itemTextColor);
+ } else {
+ itemTextColor = createDefaultColorStateList(android.R.attr.textColorPrimary);
+ }
+
+ final Drawable itemBackground = a.getDrawable(R.styleable.NavigationView_itemBackground);
if (a.hasValue(R.styleable.NavigationView_menu)) {
inflateMenu(a.getResourceId(R.styleable.NavigationView_menu, 0));
@@ -126,8 +142,9 @@
mPresenter = new NavigationMenuPresenter();
mPresenter.setId(PRESENTER_NAVIGATION_VIEW_ID);
mPresenter.initForMenu(context, mMenu);
- mPresenter.setItemTintList(itemTintList);
- mPresenter.setItemBackgroundResource(itemBackgroundResource);
+ mPresenter.setItemIconTintList(itemIconTint);
+ mPresenter.setItemTextColor(itemTextColor);
+ mPresenter.setItemBackground(itemBackground);
mMenu.addMenuPresenter(mPresenter);
addView((View) mPresenter.getMenuView(this));
@@ -229,48 +246,81 @@
}
/**
- * Return the tint applied to the icon and text of the menu items, if specified.
+ * Returns the tint which is applied to our item's icons.
*
- * @return the tint applied to the icon and text of the menu items
- * @see #setItemTintList(ColorStateList)
- * @attr ref R.styleable#NavigationView_itemTint
+ * @see #setItemIconTintList(ColorStateList)
+ *
+ * @attr ref R.styleable#NavigationView_itemIconTint
*/
@Nullable
- public ColorStateList getItemTintList() {
+ public ColorStateList getItemIconTintList() {
return mPresenter.getItemTintList();
}
/**
- * Applies a tint to the icon and text of the menu items.
+ * Set the tint which is applied to our item's icons.
*
- * @param itemTintList the tint to apply, may be {@code null} to use default tint.
- * @attr ref R.styleable#NavigationView_itemTint
+ * @param tint the tint to apply.
+ *
+ * @attr ref R.styleable#NavigationView_itemIconTint
*/
- public void setItemTintList(@Nullable ColorStateList itemTintList) {
- mPresenter.setItemTintList(itemTintList);
+ public void setItemIconTintList(@Nullable ColorStateList tint) {
+ mPresenter.setItemIconTintList(tint);
}
/**
- * Return the resource ID of background drawable for the menu items.
+ * Returns the tint which is applied to our item's icons.
*
- * @return The resource ID
+ * @see #setItemTextColor(ColorStateList)
+ *
+ * @attr ref R.styleable#NavigationView_itemTextColor
+ */
+ @Nullable
+ public ColorStateList getItemTextColor() {
+ return mPresenter.getItemTextColor();
+ }
+
+ /**
+ * Set the text color which is text to our items.
+ *
+ * @see #getItemTextColor()
+ *
+ * @attr ref R.styleable#NavigationView_itemTextColor
+ */
+ public void setItemTextColor(@Nullable ColorStateList textColor) {
+ mPresenter.setItemTextColor(textColor);
+ }
+
+ /**
+ * Returns the background drawable for the menu items.
+ *
* @see #setItemBackgroundResource(int)
+ *
* @attr ref R.styleable#NavigationView_itemBackground
*/
- @DrawableRes
- public int getItemBackgroundResource() {
- return mPresenter.getItemBackgroundResource();
+ public Drawable getItemBackground() {
+ return mPresenter.getItemBackground();
+ }
+
+ /**
+ * Set the background of the menu items to the given resource.
+ *
+ * @param resId The identifier of the resource.
+ *
+ * @attr ref R.styleable#NavigationView_itemBackground
+ */
+ public void setItemBackgroundResource(@DrawableRes int resId) {
+ setItemBackground(ContextCompat.getDrawable(getContext(), resId));
}
/**
* Set the background of the menu items to a given resource. The resource should refer to
* a Drawable object or 0 to use the background background.
*
- * @param itemBackground The identifier of the resource.
* @attr ref R.styleable#NavigationView_itemBackground
*/
- public void setItemBackgroundResource(@DrawableRes int itemBackground) {
- mPresenter.setItemBackgroundResource(itemBackground);
+ public void setItemBackground(Drawable itemBackground) {
+ mPresenter.setItemBackground(itemBackground);
}
private MenuInflater getMenuInflater() {
@@ -280,6 +330,28 @@
return mMenuInflater;
}
+ private ColorStateList createDefaultColorStateList(int baseColorThemeAttr) {
+ TypedValue value = new TypedValue();
+ if (!getContext().getTheme().resolveAttribute(baseColorThemeAttr, value, true)) {
+ return null;
+ }
+ ColorStateList baseColor = getResources().getColorStateList(value.resourceId);
+ if (!getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true)) {
+ return null;
+ }
+ int colorPrimary = value.data;
+ int defaultColor = baseColor.getDefaultColor();
+ return new ColorStateList(new int[][]{
+ DISABLED_STATE_SET,
+ CHECKED_STATE_SET,
+ EMPTY_STATE_SET
+ }, new int[]{
+ baseColor.getColorForState(DISABLED_STATE_SET, defaultColor),
+ colorPrimary,
+ defaultColor
+ });
+ }
+
/**
* Listener for handling events on navigation items.
*/
@@ -289,6 +361,8 @@
* Called when an item in the navigation menu is selected.
*
* @param item The selected item
+ *
+ * @return true to display the item as the selected item
*/
public boolean onNavigationItemSelected(MenuItem item);
}
@@ -298,7 +372,6 @@
* onSaveInstanceState().
*/
public static class SavedState extends BaseSavedState {
-
public Bundle menuState;
public SavedState(Parcel in) {
@@ -318,7 +391,6 @@
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
-
@Override
public SavedState createFromParcel(Parcel parcel) {
return new SavedState(parcel);
@@ -328,9 +400,7 @@
public SavedState[] newArray(int size) {
return new SavedState[size];
}
-
};
-
}
}