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];
             }
-
         };
-
     }
 
 }