blob: 29ac3f349d0a06574f1b26efe35b396a056e3ec5 [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
Alan Viverette617feb92013-09-09 18:09:13 -070058 public ListMenuItemView(
59 Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
60 super(context, attrs, defStyleAttr, defStyleRes);
61
62 final TypedArray a = context.obtainStyledAttributes(
63 attrs, com.android.internal.R.styleable.MenuView, defStyleAttr, defStyleRes);
64
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
Alan Viverette617feb92013-09-09 18:09:13 -070075 public ListMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
76 this(context, attrs, defStyleAttr, 0);
77 }
78
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 public ListMenuItemView(Context context, AttributeSet attrs) {
80 this(context, attrs, 0);
81 }
82
83 @Override
84 protected void onFinishInflate() {
85 super.onFinishInflate();
Alan Viveretted9ddf522013-07-15 16:43:58 -070086
87 setBackgroundDrawable(mBackground);
88
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 mTitleView = (TextView) findViewById(com.android.internal.R.id.title);
Alan Viveretted9ddf522013-07-15 16:43:58 -070090 if (mTextAppearance != -1) {
91 mTitleView.setTextAppearance(mTextAppearanceContext,
92 mTextAppearance);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 }
Alan Viveretted9ddf522013-07-15 16:43:58 -070094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 mShortcutView = (TextView) findViewById(com.android.internal.R.id.shortcut);
96 }
97
98 public void initialize(MenuItemImpl itemData, int menuType) {
99 mItemData = itemData;
Alan Viveretted9ddf522013-07-15 16:43:58 -0700100 mMenuType = menuType;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101
102 setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
Alan Viveretted9ddf522013-07-15 16:43:58 -0700103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 setTitle(itemData.getTitleForItemView(this));
105 setCheckable(itemData.isCheckable());
106 setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut());
107 setIcon(itemData.getIcon());
108 setEnabled(itemData.isEnabled());
109 }
110
Adam Powell91511032011-07-13 10:24:06 -0700111 public void setForceShowIcon(boolean forceShow) {
112 mPreserveIconSpacing = mForceShowIcon = forceShow;
113 }
114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 public void setTitle(CharSequence title) {
116 if (title != null) {
117 mTitleView.setText(title);
Alan Viveretted9ddf522013-07-15 16:43:58 -0700118
119 if (mTitleView.getVisibility() != VISIBLE) mTitleView.setVisibility(VISIBLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 } else {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700121 if (mTitleView.getVisibility() != GONE) mTitleView.setVisibility(GONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 }
123 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 public MenuItemImpl getItemData() {
126 return mItemData;
127 }
128
129 public void setCheckable(boolean checkable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 if (!checkable && mRadioButton == null && mCheckBox == null) {
131 return;
132 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 // 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;
Alan Viveretted9ddf522013-07-15 16:43:58 -0700137 final CompoundButton otherCompoundButton;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138
139 if (mItemData.isExclusiveCheckable()) {
Adam Powell8eeb4d12011-10-12 17:48:05 -0700140 if (mRadioButton == null) {
141 insertRadioButton();
142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 compoundButton = mRadioButton;
144 otherCompoundButton = mCheckBox;
145 } else {
Adam Powell8eeb4d12011-10-12 17:48:05 -0700146 if (mCheckBox == null) {
147 insertCheckBox();
148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 compoundButton = mCheckBox;
150 otherCompoundButton = mRadioButton;
151 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 if (checkable) {
154 compoundButton.setChecked(mItemData.isChecked());
Alan Viveretted9ddf522013-07-15 16:43:58 -0700155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 final int newVisibility = checkable ? VISIBLE : GONE;
157 if (compoundButton.getVisibility() != newVisibility) {
158 compoundButton.setVisibility(newVisibility);
159 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 // Make sure the other compound button isn't visible
Adam Powell8eeb4d12011-10-12 17:48:05 -0700162 if (otherCompoundButton != null && otherCompoundButton.getVisibility() != GONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 otherCompoundButton.setVisibility(GONE);
164 }
165 } else {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700166 if (mCheckBox != null) mCheckBox.setVisibility(GONE);
167 if (mRadioButton != null) mRadioButton.setVisibility(GONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 }
169 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 public void setChecked(boolean checked) {
172 CompoundButton compoundButton;
Alan Viveretted9ddf522013-07-15 16:43:58 -0700173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 if (mItemData.isExclusiveCheckable()) {
175 if (mRadioButton == null) {
176 insertRadioButton();
177 }
178 compoundButton = mRadioButton;
179 } else {
180 if (mCheckBox == null) {
181 insertCheckBox();
182 }
183 compoundButton = mCheckBox;
184 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 compoundButton.setChecked(checked);
187 }
188
189 public void setShortcut(boolean showShortcut, char shortcutKey) {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700190 final int newVisibility = (showShortcut && mItemData.shouldShowShortcut())
191 ? VISIBLE : GONE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192
193 if (newVisibility == VISIBLE) {
194 mShortcutView.setText(mItemData.getShortcutLabel());
195 }
196
197 if (mShortcutView.getVisibility() != newVisibility) {
198 mShortcutView.setVisibility(newVisibility);
199 }
200 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 public void setIcon(Drawable icon) {
Adam Powell91511032011-07-13 10:24:06 -0700203 final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon;
Adam Powelle7d46842011-01-13 21:36:09 -0800204 if (!showIcon && !mPreserveIconSpacing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 return;
206 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700207
Adam Powell91511032011-07-13 10:24:06 -0700208 if (mIconView == null && icon == null && !mPreserveIconSpacing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 return;
210 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 if (mIconView == null) {
213 insertIconView();
214 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700215
Adam Powelle7d46842011-01-13 21:36:09 -0800216 if (icon != null || mPreserveIconSpacing) {
217 mIconView.setImageDrawable(showIcon ? icon : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218
219 if (mIconView.getVisibility() != VISIBLE) {
220 mIconView.setVisibility(VISIBLE);
221 }
222 } else {
223 mIconView.setVisibility(GONE);
224 }
225 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700226
Adam Powell91511032011-07-13 10:24:06 -0700227 @Override
228 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
229 if (mIconView != null && mPreserveIconSpacing) {
230 // Enforce minimum icon spacing
Alan Viveretted9ddf522013-07-15 16:43:58 -0700231 ViewGroup.LayoutParams lp = getLayoutParams();
232 LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
Adam Powell91511032011-07-13 10:24:06 -0700233 if (lp.height > 0 && iconLp.width <= 0) {
234 iconLp.width = lp.height;
235 }
236 }
237 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
238 }
239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 private void insertIconView() {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700241 LayoutInflater inflater = getInflater();
242 mIconView = (ImageView) inflater.inflate(com.android.internal.R.layout.list_menu_item_icon,
243 this, false);
244 addView(mIconView, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700246
Alan Viverette8933efd2013-06-26 17:38:17 -0700247 private void insertRadioButton() {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700248 LayoutInflater inflater = getInflater();
249 mRadioButton =
250 (RadioButton) inflater.inflate(com.android.internal.R.layout.list_menu_item_radio,
251 this, false);
Adam Powellc3945122013-07-10 11:51:33 -0700252 addView(mRadioButton);
Alan Viverette8933efd2013-06-26 17:38:17 -0700253 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700254
Alan Viverette8933efd2013-06-26 17:38:17 -0700255 private void insertCheckBox() {
Alan Viveretted9ddf522013-07-15 16:43:58 -0700256 LayoutInflater inflater = getInflater();
257 mCheckBox =
258 (CheckBox) inflater.inflate(com.android.internal.R.layout.list_menu_item_checkbox,
259 this, false);
Adam Powellc3945122013-07-10 11:51:33 -0700260 addView(mCheckBox);
Alan Viverette8933efd2013-06-26 17:38:17 -0700261 }
262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 public boolean prefersCondensedTitle() {
264 return false;
265 }
266
267 public boolean showsIcon() {
Adam Powell91511032011-07-13 10:24:06 -0700268 return mForceShowIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 }
Alan Viveretted9ddf522013-07-15 16:43:58 -0700270
Adam Powell696cba52011-03-29 10:38:16 -0700271 private LayoutInflater getInflater() {
272 if (mInflater == null) {
273 mInflater = LayoutInflater.from(mContext);
274 }
275 return mInflater;
276 }
Alan Viverette058ac7c2013-08-19 16:44:30 -0700277
278 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800279 public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
280 super.onInitializeAccessibilityNodeInfoInternal(info);
Alan Viverette058ac7c2013-08-19 16:44:30 -0700281
282 if (mItemData != null && mItemData.hasSubMenu()) {
Svetoslav Ganovcb8ed392013-08-23 20:37:28 -0700283 info.setCanOpenPopup(true);
Alan Viverette058ac7c2013-08-19 16:44:30 -0700284 }
285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286}