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