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