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