ActionMenuItemView.java revision 7b5e9e6c1c7098b6d7b2c6f9ab0c316f0f66109e
1/* 2 * Copyright (C) 2010 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.Resources; 21import android.graphics.Rect; 22import android.graphics.drawable.Drawable; 23import android.text.TextUtils; 24import android.util.AttributeSet; 25import android.view.Gravity; 26import android.view.View; 27import android.widget.Button; 28import android.widget.ImageButton; 29import android.widget.LinearLayout; 30import android.widget.Toast; 31 32/** 33 * @hide 34 */ 35public class ActionMenuItemView extends LinearLayout 36 implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener, 37 ActionMenuView.ActionMenuChildView { 38 private static final String TAG = "ActionMenuItemView"; 39 40 private MenuItemImpl mItemData; 41 private CharSequence mTitle; 42 private MenuBuilder.ItemInvoker mItemInvoker; 43 44 private ImageButton mImageButton; 45 private Button mTextButton; 46 private boolean mAllowTextWithIcon; 47 private boolean mShowTextAllCaps; 48 private boolean mExpandedFormat; 49 50 public ActionMenuItemView(Context context) { 51 this(context, null); 52 } 53 54 public ActionMenuItemView(Context context, AttributeSet attrs) { 55 this(context, attrs, 0); 56 } 57 58 public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) { 59 super(context, attrs, defStyle); 60 final Resources res = context.getResources(); 61 mAllowTextWithIcon = res.getBoolean( 62 com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon); 63 mShowTextAllCaps = res.getBoolean(com.android.internal.R.bool.config_actionMenuItemAllCaps); 64 } 65 66 @Override 67 public void onFinishInflate() { 68 mImageButton = (ImageButton) findViewById(com.android.internal.R.id.imageButton); 69 mTextButton = (Button) findViewById(com.android.internal.R.id.textButton); 70 mImageButton.setOnClickListener(this); 71 mTextButton.setOnClickListener(this); 72 mImageButton.setOnLongClickListener(this); 73 setOnClickListener(this); 74 setOnLongClickListener(this); 75 } 76 77 public MenuItemImpl getItemData() { 78 return mItemData; 79 } 80 81 public void initialize(MenuItemImpl itemData, int menuType) { 82 mItemData = itemData; 83 84 setIcon(itemData.getIcon()); 85 setTitle(itemData.getTitleForItemView(this)); // Title only takes effect if there is no icon 86 setId(itemData.getItemId()); 87 88 setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); 89 setEnabled(itemData.isEnabled()); 90 } 91 92 @Override 93 public void setEnabled(boolean enabled) { 94 super.setEnabled(enabled); 95 mImageButton.setEnabled(enabled); 96 mTextButton.setEnabled(enabled); 97 } 98 99 public void onClick(View v) { 100 if (mItemInvoker != null) { 101 mItemInvoker.invokeItem(mItemData); 102 } 103 } 104 105 public void setItemInvoker(MenuBuilder.ItemInvoker invoker) { 106 mItemInvoker = invoker; 107 } 108 109 public boolean prefersCondensedTitle() { 110 return true; 111 } 112 113 public void setCheckable(boolean checkable) { 114 // TODO Support checkable action items 115 } 116 117 public void setChecked(boolean checked) { 118 // TODO Support checkable action items 119 } 120 121 public void setExpandedFormat(boolean expandedFormat) { 122 if (mExpandedFormat != expandedFormat) { 123 mExpandedFormat = expandedFormat; 124 if (mItemData != null) { 125 mItemData.actionFormatChanged(); 126 } 127 } 128 } 129 130 private void updateTextButtonVisibility() { 131 boolean visible = !TextUtils.isEmpty(mTextButton.getText()); 132 visible &= mImageButton.getDrawable() == null || 133 (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat)); 134 135 mTextButton.setVisibility(visible ? VISIBLE : GONE); 136 } 137 138 public void setIcon(Drawable icon) { 139 mImageButton.setImageDrawable(icon); 140 if (icon != null) { 141 mImageButton.setVisibility(VISIBLE); 142 } else { 143 mImageButton.setVisibility(GONE); 144 } 145 146 updateTextButtonVisibility(); 147 } 148 149 public boolean hasText() { 150 return mTextButton.getVisibility() != GONE; 151 } 152 153 public void setShortcut(boolean showShortcut, char shortcutKey) { 154 // Action buttons don't show text for shortcut keys. 155 } 156 157 public void setTitle(CharSequence title) { 158 mTitle = title; 159 160 // populate accessibility description with title 161 setContentDescription(title); 162 163 mTextButton.setText(mTitle); 164 165 updateTextButtonVisibility(); 166 } 167 168 public boolean showsIcon() { 169 return true; 170 } 171 172 public boolean needsDividerBefore() { 173 return hasText() && mItemData.getIcon() == null; 174 } 175 176 public boolean needsDividerAfter() { 177 return hasText(); 178 } 179 180 @Override 181 public boolean onLongClick(View v) { 182 if (hasText()) { 183 // Don't show the cheat sheet for items that already show text. 184 return false; 185 } 186 187 final int[] screenPos = new int[2]; 188 final Rect displayFrame = new Rect(); 189 getLocationOnScreen(screenPos); 190 getWindowVisibleDisplayFrame(displayFrame); 191 192 final Context context = getContext(); 193 final int width = getWidth(); 194 final int height = getHeight(); 195 final int midy = screenPos[1] + height / 2; 196 final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; 197 198 Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT); 199 if (midy < displayFrame.height()) { 200 // Show along the top; follow action buttons 201 cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT, 202 screenWidth - screenPos[0] - width / 2, height); 203 } else { 204 // Show along the bottom center 205 cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); 206 } 207 cheatSheet.show(); 208 return true; 209 } 210} 211