ListMenuItemView.java revision da10fdd1400ecfd8d7f2e55651dd528d0614dfc5
1/*
2 * Copyright (C) 2006 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
17package android.support.v7.internal.view.menu;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.graphics.drawable.Drawable;
22import android.support.v7.appcompat.R;
23import android.util.AttributeSet;
24import android.view.LayoutInflater;
25import android.view.View;
26import android.view.ViewGroup;
27import android.widget.CheckBox;
28import android.widget.CompoundButton;
29import android.widget.ImageView;
30import android.widget.LinearLayout;
31import android.widget.RadioButton;
32import android.widget.TextView;
33
34/**
35 * The item view for each item in the ListView-based MenuViews.
36 */
37public class ListMenuItemView extends LinearLayout implements MenuView.ItemView {
38
39    private static final String TAG = "ListMenuItemView";
40    private MenuItemImpl mItemData;
41
42    private ImageView mIconView;
43    private RadioButton mRadioButton;
44    private TextView mTitleView;
45    private CheckBox mCheckBox;
46    private TextView mShortcutView;
47
48    private Drawable mBackground;
49    private int mTextAppearance;
50    private Context mTextAppearanceContext;
51    private boolean mPreserveIconSpacing;
52
53    private int mMenuType;
54
55    private Context mContext;
56    private LayoutInflater mInflater;
57
58    private boolean mForceShowIcon;
59
60    public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) {
61        super(context, attrs);
62        mContext = context;
63
64        TypedArray a =
65                context.obtainStyledAttributes(
66                        attrs, R.styleable.MenuView, defStyle, 0);
67
68        mBackground = a.getDrawable(R.styleable.MenuView_android_itemBackground);
69        mTextAppearance = a.getResourceId(R.styleable.
70                MenuView_android_itemTextAppearance, -1);
71        mPreserveIconSpacing = a.getBoolean(
72                R.styleable.MenuView_android_preserveIconSpacing, false);
73        mTextAppearanceContext = context;
74
75        a.recycle();
76    }
77
78    public ListMenuItemView(Context context, AttributeSet attrs) {
79        this(context, attrs, 0);
80    }
81
82    @Override
83    protected void onFinishInflate() {
84        super.onFinishInflate();
85
86        setBackgroundDrawable(mBackground);
87
88        mTitleView = (TextView) findViewById(R.id.title);
89        if (mTextAppearance != -1) {
90            mTitleView.setTextAppearance(mTextAppearanceContext,
91                    mTextAppearance);
92        }
93
94        mShortcutView = (TextView) findViewById(R.id.shortcut);
95    }
96
97    public void initialize(MenuItemImpl itemData, int menuType) {
98        mItemData = itemData;
99        mMenuType = menuType;
100
101        setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
102
103        setTitle(itemData.getTitleForItemView(this));
104        setCheckable(itemData.isCheckable());
105        setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut());
106        setIcon(itemData.getIcon());
107        setEnabled(itemData.isEnabled());
108    }
109
110    public void setForceShowIcon(boolean forceShow) {
111        mPreserveIconSpacing = mForceShowIcon = forceShow;
112    }
113
114    public void setTitle(CharSequence title) {
115        if (title != null) {
116            mTitleView.setText(title);
117
118            if (mTitleView.getVisibility() != VISIBLE) {
119                mTitleView.setVisibility(VISIBLE);
120            }
121        } else {
122            if (mTitleView.getVisibility() != GONE) {
123                mTitleView.setVisibility(GONE);
124            }
125        }
126    }
127
128    public MenuItemImpl getItemData() {
129        return mItemData;
130    }
131
132    public void setCheckable(boolean checkable) {
133        if (!checkable && mRadioButton == null && mCheckBox == null) {
134            return;
135        }
136
137        // Depending on whether its exclusive check or not, the checkbox or
138        // radio button will be the one in use (and the other will be otherCompoundButton)
139        final CompoundButton compoundButton;
140        final CompoundButton otherCompoundButton;
141
142        if (mItemData.isExclusiveCheckable()) {
143            if (mRadioButton == null) {
144                insertRadioButton();
145            }
146            compoundButton = mRadioButton;
147            otherCompoundButton = mCheckBox;
148        } else {
149            if (mCheckBox == null) {
150                insertCheckBox();
151            }
152            compoundButton = mCheckBox;
153            otherCompoundButton = mRadioButton;
154        }
155
156        if (checkable) {
157            compoundButton.setChecked(mItemData.isChecked());
158
159            final int newVisibility = checkable ? VISIBLE : GONE;
160            if (compoundButton.getVisibility() != newVisibility) {
161                compoundButton.setVisibility(newVisibility);
162            }
163
164            // Make sure the other compound button isn't visible
165            if (otherCompoundButton != null && otherCompoundButton.getVisibility() != GONE) {
166                otherCompoundButton.setVisibility(GONE);
167            }
168        } else {
169            if (mCheckBox != null) {
170                mCheckBox.setVisibility(GONE);
171            }
172            if (mRadioButton != null) {
173                mRadioButton.setVisibility(GONE);
174            }
175        }
176    }
177
178    public void setChecked(boolean checked) {
179        CompoundButton compoundButton;
180
181        if (mItemData.isExclusiveCheckable()) {
182            if (mRadioButton == null) {
183                insertRadioButton();
184            }
185            compoundButton = mRadioButton;
186        } else {
187            if (mCheckBox == null) {
188                insertCheckBox();
189            }
190            compoundButton = mCheckBox;
191        }
192
193        compoundButton.setChecked(checked);
194    }
195
196    public void setShortcut(boolean showShortcut, char shortcutKey) {
197        final int newVisibility = (showShortcut && mItemData.shouldShowShortcut())
198                ? VISIBLE : GONE;
199
200        if (newVisibility == VISIBLE) {
201            mShortcutView.setText(mItemData.getShortcutLabel());
202        }
203
204        if (mShortcutView.getVisibility() != newVisibility) {
205            mShortcutView.setVisibility(newVisibility);
206        }
207    }
208
209    public void setIcon(Drawable icon) {
210        final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon;
211        if (!showIcon && !mPreserveIconSpacing) {
212            return;
213        }
214
215        if (mIconView == null && icon == null && !mPreserveIconSpacing) {
216            return;
217        }
218
219        if (mIconView == null) {
220            insertIconView();
221        }
222
223        if (icon != null || mPreserveIconSpacing) {
224            mIconView.setImageDrawable(showIcon ? icon : null);
225
226            if (mIconView.getVisibility() != VISIBLE) {
227                mIconView.setVisibility(VISIBLE);
228            }
229        } else {
230            mIconView.setVisibility(GONE);
231        }
232    }
233
234    @Override
235    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
236        if (mIconView != null && mPreserveIconSpacing) {
237            // Enforce minimum icon spacing
238            ViewGroup.LayoutParams lp = getLayoutParams();
239            LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
240            if (lp.height > 0 && iconLp.width <= 0) {
241                iconLp.width = lp.height;
242            }
243        }
244        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
245    }
246
247    private void insertIconView() {
248        LayoutInflater inflater = getInflater();
249        mIconView = (ImageView) inflater.inflate(R.layout.list_menu_item_icon,
250                this, false);
251        addView(mIconView, 0);
252    }
253
254    private void insertRadioButton() {
255        LayoutInflater inflater = getInflater();
256        mRadioButton =
257                (RadioButton) inflater.inflate(R.layout.list_menu_item_radio,
258                        this, false);
259        addView(mRadioButton);
260    }
261
262    private void insertCheckBox() {
263        LayoutInflater inflater = getInflater();
264        mCheckBox =
265                (CheckBox) inflater.inflate(R.layout.list_menu_item_checkbox,
266                        this, false);
267        addView(mCheckBox);
268    }
269
270    public boolean prefersCondensedTitle() {
271        return false;
272    }
273
274    public boolean showsIcon() {
275        return mForceShowIcon;
276    }
277
278    private LayoutInflater getInflater() {
279        if (mInflater == null) {
280            mInflater = LayoutInflater.from(mContext);
281        }
282        return mInflater;
283    }
284}
285
286