blob: a2a4acc75e39ab01d5654185d555cf6212ad092b [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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 com.android.internal.view.menu;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.graphics.drawable.Drawable;
22import android.util.AttributeSet;
23import android.view.LayoutInflater;
24import android.view.View;
Adam Powell91511032011-07-13 10:24:06 -070025import android.view.ViewGroup;
Alan Viverette058ac7c2013-08-19 16:44:30 -070026import android.view.accessibility.AccessibilityNodeInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.widget.CheckBox;
28import android.widget.CompoundButton;
29import android.widget.ImageView;
Alan Viveretted9ddf522013-07-15 16:43:58 -070030import android.widget.LinearLayout;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.widget.RadioButton;
32import android.widget.TextView;
33
34/**
35 * The item view for each item in the ListView-based MenuViews.
36 */
Alan Viveretted9ddf522013-07-15 16:43:58 -070037public class ListMenuItemView extends LinearLayout implements MenuView.ItemView {
38 private static final String TAG = "ListMenuItemView";
39 private MenuItemImpl mItemData;
40
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041 private ImageView mIconView;
42 private RadioButton mRadioButton;
43 private TextView mTitleView;
44 private CheckBox mCheckBox;
45 private TextView mShortcutView;
Alan Viveretted9ddf522013-07-15 16:43:58 -070046
47 private Drawable mBackground;
48 private int mTextAppearance;
49 private Context mTextAppearanceContext;
50 private boolean mPreserveIconSpacing;
51
52 private int mMenuType;
53
Adam Powell696cba52011-03-29 10:38:16 -070054 private LayoutInflater mInflater;
55
Adam Powell91511032011-07-13 10:24:06 -070056 private boolean mForceShowIcon;
57
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) {
59 super(context, attrs);
Alan Viveretted9ddf522013-07-15 16:43:58 -070060
61 TypedArray a =
62 context.obtainStyledAttributes(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);
Alan Viveretted9ddf522013-07-15 16:43:58 -070064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 mBackground = a.getDrawable(com.android.internal.R.styleable.MenuView_itemBackground);
Alan Viveretted9ddf522013-07-15 16:43:58 -070066 mTextAppearance = a.getResourceId(com.android.internal.R.styleable.
67 MenuView_itemTextAppearance, -1);
Adam Powelle7d46842011-01-13 21:36:09 -080068 mPreserveIconSpacing = a.getBoolean(
69 com.android.internal.R.styleable.MenuView_preserveIconSpacing, false);
Alan Viveretted9ddf522013-07-15 16:43:58 -070070 mTextAppearanceContext = context;
71
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 a.recycle();
73 }
74
75 public ListMenuItemView(Context context, AttributeSet attrs) {
76 this(context, attrs, 0);
77 }
78
79 @Override
80 protected void onFinishInflate() {
81 super.onFinishInflate();
Alan Viveretted9ddf522013-07-15 16:43:58 -070082
83 setBackgroundDrawable(mBackground);
84
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 mTitleView = (TextView) findViewById(com.android.internal.R.id.title);
Alan Viveretted9ddf522013-07-15 16:43:58 -070086 if (mTextAppearance != -1) {
87 mTitleView.setTextAppearance(mTextAppearanceContext,
88 mTextAppearance);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 }
Alan Viveretted9ddf522013-07-15 16:43:58 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 mShortcutView = (TextView) findViewById(com.android.internal.R.id.shortcut);
92 }
93
94 public void initialize(MenuItemImpl itemData, int menuType) {
95 mItemData = itemData;
Alan Viveretted9ddf522013-07-15 16:43:58 -070096 mMenuType = menuType;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097
98 setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
Alan Viveretted9ddf522013-07-15 16:43:58 -070099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 setTitle(itemData.getTitleForItemView(this));
101 setCheckable(itemData.isCheckable());
102 setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut());
103 setIcon(itemData.getIcon());
104 setEnabled(itemData.isEnabled());
105 }
106
Adam Powell91511032011-07-13 10:24:06 -0700107 public void setForceShowIcon(boolean forceShow) {
108 mPreserveIconSpacing = mForceShowIcon = forceShow;
109 }
110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 public void setTitle(CharSequence title) {
112 if (title != null) {
113 mTitleView.setText(title);
Alan Viveretted9ddf522013-07-15 16:43:58 -0700114
115 if (mTitleView.getVisibility() != VISIBLE) mTitleView.setVisibility(VISIBLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 } else {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700117 if (mTitleView.getVisibility() != GONE) mTitleView.setVisibility(GONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 }
119 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 public MenuItemImpl getItemData() {
122 return mItemData;
123 }
124
125 public void setCheckable(boolean checkable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 if (!checkable && mRadioButton == null && mCheckBox == null) {
127 return;
128 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 // Depending on whether its exclusive check or not, the checkbox or
131 // radio button will be the one in use (and the other will be otherCompoundButton)
132 final CompoundButton compoundButton;
Alan Viveretted9ddf522013-07-15 16:43:58 -0700133 final CompoundButton otherCompoundButton;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
135 if (mItemData.isExclusiveCheckable()) {
Adam Powell8eeb4d12011-10-12 17:48:05 -0700136 if (mRadioButton == null) {
137 insertRadioButton();
138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 compoundButton = mRadioButton;
140 otherCompoundButton = mCheckBox;
141 } else {
Adam Powell8eeb4d12011-10-12 17:48:05 -0700142 if (mCheckBox == null) {
143 insertCheckBox();
144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 compoundButton = mCheckBox;
146 otherCompoundButton = mRadioButton;
147 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 if (checkable) {
150 compoundButton.setChecked(mItemData.isChecked());
Alan Viveretted9ddf522013-07-15 16:43:58 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 final int newVisibility = checkable ? VISIBLE : GONE;
153 if (compoundButton.getVisibility() != newVisibility) {
154 compoundButton.setVisibility(newVisibility);
155 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 // Make sure the other compound button isn't visible
Adam Powell8eeb4d12011-10-12 17:48:05 -0700158 if (otherCompoundButton != null && otherCompoundButton.getVisibility() != GONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 otherCompoundButton.setVisibility(GONE);
160 }
161 } else {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700162 if (mCheckBox != null) mCheckBox.setVisibility(GONE);
163 if (mRadioButton != null) mRadioButton.setVisibility(GONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 }
165 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 public void setChecked(boolean checked) {
168 CompoundButton compoundButton;
Alan Viveretted9ddf522013-07-15 16:43:58 -0700169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 if (mItemData.isExclusiveCheckable()) {
171 if (mRadioButton == null) {
172 insertRadioButton();
173 }
174 compoundButton = mRadioButton;
175 } else {
176 if (mCheckBox == null) {
177 insertCheckBox();
178 }
179 compoundButton = mCheckBox;
180 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 compoundButton.setChecked(checked);
183 }
184
185 public void setShortcut(boolean showShortcut, char shortcutKey) {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700186 final int newVisibility = (showShortcut && mItemData.shouldShowShortcut())
187 ? VISIBLE : GONE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
189 if (newVisibility == VISIBLE) {
190 mShortcutView.setText(mItemData.getShortcutLabel());
191 }
192
193 if (mShortcutView.getVisibility() != newVisibility) {
194 mShortcutView.setVisibility(newVisibility);
195 }
196 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 public void setIcon(Drawable icon) {
Adam Powell91511032011-07-13 10:24:06 -0700199 final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon;
Adam Powelle7d46842011-01-13 21:36:09 -0800200 if (!showIcon && !mPreserveIconSpacing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 return;
202 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700203
Adam Powell91511032011-07-13 10:24:06 -0700204 if (mIconView == null && icon == null && !mPreserveIconSpacing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 return;
206 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 if (mIconView == null) {
209 insertIconView();
210 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700211
Adam Powelle7d46842011-01-13 21:36:09 -0800212 if (icon != null || mPreserveIconSpacing) {
213 mIconView.setImageDrawable(showIcon ? icon : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214
215 if (mIconView.getVisibility() != VISIBLE) {
216 mIconView.setVisibility(VISIBLE);
217 }
218 } else {
219 mIconView.setVisibility(GONE);
220 }
221 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700222
Adam Powell91511032011-07-13 10:24:06 -0700223 @Override
224 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
225 if (mIconView != null && mPreserveIconSpacing) {
226 // Enforce minimum icon spacing
Alan Viveretted9ddf522013-07-15 16:43:58 -0700227 ViewGroup.LayoutParams lp = getLayoutParams();
228 LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
Adam Powell91511032011-07-13 10:24:06 -0700229 if (lp.height > 0 && iconLp.width <= 0) {
230 iconLp.width = lp.height;
231 }
232 }
233 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
234 }
235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 private void insertIconView() {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700237 LayoutInflater inflater = getInflater();
238 mIconView = (ImageView) inflater.inflate(com.android.internal.R.layout.list_menu_item_icon,
239 this, false);
240 addView(mIconView, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700242
Alan Viverette8933efd2013-06-26 17:38:17 -0700243 private void insertRadioButton() {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700244 LayoutInflater inflater = getInflater();
245 mRadioButton =
246 (RadioButton) inflater.inflate(com.android.internal.R.layout.list_menu_item_radio,
247 this, false);
Adam Powellc3945122013-07-10 11:51:33 -0700248 addView(mRadioButton);
Alan Viverette8933efd2013-06-26 17:38:17 -0700249 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700250
Alan Viverette8933efd2013-06-26 17:38:17 -0700251 private void insertCheckBox() {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700252 LayoutInflater inflater = getInflater();
253 mCheckBox =
254 (CheckBox) inflater.inflate(com.android.internal.R.layout.list_menu_item_checkbox,
255 this, false);
Adam Powellc3945122013-07-10 11:51:33 -0700256 addView(mCheckBox);
Alan Viverette8933efd2013-06-26 17:38:17 -0700257 }
258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 public boolean prefersCondensedTitle() {
260 return false;
261 }
262
263 public boolean showsIcon() {
Adam Powell91511032011-07-13 10:24:06 -0700264 return mForceShowIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700266
Adam Powell696cba52011-03-29 10:38:16 -0700267 private LayoutInflater getInflater() {
268 if (mInflater == null) {
269 mInflater = LayoutInflater.from(mContext);
270 }
271 return mInflater;
272 }
Alan Viverette058ac7c2013-08-19 16:44:30 -0700273
274 @Override
275 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
276 super.onInitializeAccessibilityNodeInfo(info);
277
278 if (mItemData != null && mItemData.hasSubMenu()) {
Svetoslav Ganovcb8ed392013-08-23 20:37:28 -0700279 info.setCanOpenPopup(true);
Alan Viverette058ac7c2013-08-19 16:44:30 -0700280 }
281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282}