1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.support.design.internal;
18 
19 import android.content.Context;
20 import android.content.res.ColorStateList;
21 import android.graphics.Color;
22 import android.graphics.drawable.ColorDrawable;
23 import android.graphics.drawable.Drawable;
24 import android.graphics.drawable.StateListDrawable;
25 import android.support.design.R;
26 import android.support.v4.graphics.drawable.DrawableCompat;
27 import android.support.v4.widget.TextViewCompat;
28 import android.support.v7.view.menu.MenuItemImpl;
29 import android.support.v7.view.menu.MenuView;
30 import android.util.AttributeSet;
31 import android.util.TypedValue;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.view.ViewStub;
35 import android.widget.CheckedTextView;
36 import android.widget.FrameLayout;
37 
38 /**
39  * @hide
40  */
41 public class NavigationMenuItemView extends ForegroundLinearLayout implements MenuView.ItemView {
42 
43     private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
44 
45     private final int mIconSize;
46 
47     private final CheckedTextView mTextView;
48 
49     private FrameLayout mActionArea;
50 
51     private MenuItemImpl mItemData;
52 
53     private ColorStateList mIconTintList;
54 
NavigationMenuItemView(Context context)55     public NavigationMenuItemView(Context context) {
56         this(context, null);
57     }
58 
NavigationMenuItemView(Context context, AttributeSet attrs)59     public NavigationMenuItemView(Context context, AttributeSet attrs) {
60         this(context, attrs, 0);
61     }
62 
NavigationMenuItemView(Context context, AttributeSet attrs, int defStyleAttr)63     public NavigationMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
64         super(context, attrs, defStyleAttr);
65         setOrientation(HORIZONTAL);
66         LayoutInflater.from(context).inflate(R.layout.design_navigation_menu_item, this, true);
67         mIconSize = context.getResources().getDimensionPixelSize(
68                 R.dimen.design_navigation_icon_size);
69         mTextView = (CheckedTextView) findViewById(R.id.design_menu_item_text);
70         mTextView.setDuplicateParentStateEnabled(true);
71     }
72 
73     @Override
initialize(MenuItemImpl itemData, int menuType)74     public void initialize(MenuItemImpl itemData, int menuType) {
75         mItemData = itemData;
76 
77         setVisibility(itemData.isVisible() ? VISIBLE : GONE);
78 
79         if (getBackground() == null) {
80             setBackgroundDrawable(createDefaultBackground());
81         }
82 
83         setCheckable(itemData.isCheckable());
84         setChecked(itemData.isChecked());
85         setEnabled(itemData.isEnabled());
86         setTitle(itemData.getTitle());
87         setIcon(itemData.getIcon());
88         setActionView(itemData.getActionView());
89     }
90 
recycle()91     public void recycle() {
92         if (mActionArea != null) {
93             mActionArea.removeAllViews();
94         }
95         mTextView.setCompoundDrawables(null, null, null, null);
96     }
97 
setActionView(View actionView)98     private void setActionView(View actionView) {
99         if (mActionArea == null) {
100             mActionArea = (FrameLayout) ((ViewStub) findViewById(
101                     R.id.design_menu_item_action_area_stub)).inflate();
102         }
103         mActionArea.removeAllViews();
104         if (actionView != null) {
105             mActionArea.addView(actionView);
106         }
107     }
108 
createDefaultBackground()109     private StateListDrawable createDefaultBackground() {
110         TypedValue value = new TypedValue();
111         if (getContext().getTheme().resolveAttribute(
112                 android.support.v7.appcompat.R.attr.colorControlHighlight, value, true)) {
113             StateListDrawable drawable = new StateListDrawable();
114             drawable.addState(CHECKED_STATE_SET, new ColorDrawable(value.data));
115             drawable.addState(EMPTY_STATE_SET, new ColorDrawable(Color.TRANSPARENT));
116             return drawable;
117         }
118         return null;
119     }
120 
121     @Override
getItemData()122     public MenuItemImpl getItemData() {
123         return mItemData;
124     }
125 
126     @Override
setTitle(CharSequence title)127     public void setTitle(CharSequence title) {
128         mTextView.setText(title);
129     }
130 
131     @Override
setCheckable(boolean checkable)132     public void setCheckable(boolean checkable) {
133         refreshDrawableState();
134     }
135 
136     @Override
setChecked(boolean checked)137     public void setChecked(boolean checked) {
138         refreshDrawableState();
139         mTextView.setChecked(checked);
140     }
141 
142     @Override
setShortcut(boolean showShortcut, char shortcutKey)143     public void setShortcut(boolean showShortcut, char shortcutKey) {
144     }
145 
146     @Override
setIcon(Drawable icon)147     public void setIcon(Drawable icon) {
148         if (icon != null) {
149             Drawable.ConstantState state = icon.getConstantState();
150             icon = DrawableCompat.wrap(state == null ? icon : state.newDrawable()).mutate();
151             icon.setBounds(0, 0, mIconSize, mIconSize);
152             DrawableCompat.setTintList(icon, mIconTintList);
153         }
154         TextViewCompat.setCompoundDrawablesRelative(mTextView, icon, null, null, null);
155     }
156 
157     @Override
prefersCondensedTitle()158     public boolean prefersCondensedTitle() {
159         return false;
160     }
161 
162     @Override
showsIcon()163     public boolean showsIcon() {
164         return true;
165     }
166 
167     @Override
onCreateDrawableState(int extraSpace)168     protected int[] onCreateDrawableState(int extraSpace) {
169         final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
170         if (mItemData != null && mItemData.isCheckable() && mItemData.isChecked()) {
171             mergeDrawableStates(drawableState, CHECKED_STATE_SET);
172         }
173         return drawableState;
174     }
175 
setIconTintList(ColorStateList tintList)176     void setIconTintList(ColorStateList tintList) {
177         mIconTintList = tintList;
178         if (mItemData != null) {
179             // Update the icon so that the tint takes effect
180             setIcon(mItemData.getIcon());
181         }
182     }
183 
setTextAppearance(Context context, int textAppearance)184     public void setTextAppearance(Context context, int textAppearance) {
185         mTextView.setTextAppearance(context, textAppearance);
186     }
187 
setTextColor(ColorStateList colors)188     public void setTextColor(ColorStateList colors) {
189         mTextView.setTextColor(colors);
190     }
191 
192 }
193