ListMenuItemView.java revision 617feb99a06e7ffb3894e86a286bf30e085f321a
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( 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 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, int defStyleAttr) { 76 this(context, attrs, defStyleAttr, 0); 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(com.android.internal.R.id.title); 90 if (mTextAppearance != -1) { 91 mTitleView.setTextAppearance(mTextAppearanceContext, 92 mTextAppearance); 93 } 94 95 mShortcutView = (TextView) findViewById(com.android.internal.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) mCheckBox.setVisibility(GONE); 167 if (mRadioButton != null) mRadioButton.setVisibility(GONE); 168 } 169 } 170 171 public void setChecked(boolean checked) { 172 CompoundButton compoundButton; 173 174 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 } 185 186 compoundButton.setChecked(checked); 187 } 188 189 public void setShortcut(boolean showShortcut, char shortcutKey) { 190 final int newVisibility = (showShortcut && mItemData.shouldShowShortcut()) 191 ? VISIBLE : GONE; 192 193 if (newVisibility == VISIBLE) { 194 mShortcutView.setText(mItemData.getShortcutLabel()); 195 } 196 197 if (mShortcutView.getVisibility() != newVisibility) { 198 mShortcutView.setVisibility(newVisibility); 199 } 200 } 201 202 public void setIcon(Drawable icon) { 203 final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon; 204 if (!showIcon && !mPreserveIconSpacing) { 205 return; 206 } 207 208 if (mIconView == null && icon == null && !mPreserveIconSpacing) { 209 return; 210 } 211 212 if (mIconView == null) { 213 insertIconView(); 214 } 215 216 if (icon != null || mPreserveIconSpacing) { 217 mIconView.setImageDrawable(showIcon ? icon : null); 218 219 if (mIconView.getVisibility() != VISIBLE) { 220 mIconView.setVisibility(VISIBLE); 221 } 222 } else { 223 mIconView.setVisibility(GONE); 224 } 225 } 226 227 @Override 228 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 229 if (mIconView != null && mPreserveIconSpacing) { 230 // Enforce minimum icon spacing 231 ViewGroup.LayoutParams lp = getLayoutParams(); 232 LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); 233 if (lp.height > 0 && iconLp.width <= 0) { 234 iconLp.width = lp.height; 235 } 236 } 237 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 238 } 239 240 private void insertIconView() { 241 LayoutInflater inflater = getInflater(); 242 mIconView = (ImageView) inflater.inflate(com.android.internal.R.layout.list_menu_item_icon, 243 this, false); 244 addView(mIconView, 0); 245 } 246 247 private void insertRadioButton() { 248 LayoutInflater inflater = getInflater(); 249 mRadioButton = 250 (RadioButton) inflater.inflate(com.android.internal.R.layout.list_menu_item_radio, 251 this, false); 252 addView(mRadioButton); 253 } 254 255 private void insertCheckBox() { 256 LayoutInflater inflater = getInflater(); 257 mCheckBox = 258 (CheckBox) inflater.inflate(com.android.internal.R.layout.list_menu_item_checkbox, 259 this, false); 260 addView(mCheckBox); 261 } 262 263 public boolean prefersCondensedTitle() { 264 return false; 265 } 266 267 public boolean showsIcon() { 268 return mForceShowIcon; 269 } 270 271 private LayoutInflater getInflater() { 272 if (mInflater == null) { 273 mInflater = LayoutInflater.from(mContext); 274 } 275 return mInflater; 276 } 277 278 @Override 279 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 280 super.onInitializeAccessibilityNodeInfo(info); 281 282 if (mItemData != null && mItemData.hasSubMenu()) { 283 info.setCanOpenPopup(true); 284 } 285 } 286} 287