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