Home | History | Annotate | Download | only in menu
      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 
     17 package com.android.internal.view.menu;
     18 
     19 import android.content.Context;
     20 import android.content.res.TypedArray;
     21 import android.graphics.drawable.Drawable;
     22 import android.util.AttributeSet;
     23 import android.view.LayoutInflater;
     24 import android.view.View;
     25 import android.view.ViewGroup;
     26 import android.view.accessibility.AccessibilityNodeInfo;
     27 import android.widget.CheckBox;
     28 import android.widget.CompoundButton;
     29 import android.widget.ImageView;
     30 import android.widget.LinearLayout;
     31 import android.widget.RadioButton;
     32 import android.widget.TextView;
     33 
     34 /**
     35  * The item view for each item in the ListView-based MenuViews.
     36  */
     37 public 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.setCanOpenPopup(true);
    280         }
    281     }
    282 }
    283