- <menu xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:id="@+id/menu_edit"
- android:icon="@android:drawable/ic_menu_edit"
- android:showAsAction="ifRoom|withText"
- android:title="Edit"/>
- <item
- android:id="@+id/menu_save"
- android:showAsAction="ifRoom"
- android:title="Save"/>
- <item
- android:id="@+id/menu_delete"
- android:icon="@android:drawable/ic_menu_delete"
- android:showAsAction="ifRoom"
- android:title="Delete"/>
- </menu>
android:showAsAction に ifRoom を指定すると領域があるときは Action Item として表示されます。
android:icon が指定されていないときは android:title に指定されている文字列が表示されますが、 android:icon が指定されていたらデフォルトでは android:title の文字列は表示されません。
android:showAsAction に withText を指定すると、
ハンドセット縦画面 : アイコンだけ
ハンドセット横画面 : アイコン + 文字列
タブレット縦画面 : アイコン + 文字列
タブレット横画面 : アイコン + 文字列
のような表示になります。
ハンドセット縦画面
ハンドセット横画面
この条件がどこで決まっているのか調べました。
---
まず、Menu オブジェクトの View を作っているベースクラスが BaseMenuPresentar です。このクラスは MenuPresenter インタフェースを実装しています。 このクラスのコンストラクタで指定されたリソースID (mMenuLayoutRes) が
- 53 public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) {
- 54 mSystemContext = context;
- 55 mSystemInflater = LayoutInflater.from(context);
- 56 mMenuLayoutRes = menuLayoutRes;
- 57 mItemLayoutRes = itemLayoutRes;
- 58 }
getMenuView でインフレートされて Menu の View として返されます。
- 67 @Override
- 68 public MenuView getMenuView(ViewGroup root) {
- 69 if (mMenuView == null) {
- 70 mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false);
- 71 mMenuView.initialize(mMenu);
- 72 updateMenuView(true);
- 73 }
- 74
- 75 return mMenuView;
- 76 }
この BaseMenuPresenter のインスタンスを生成しているのが ActionMenuPresenter です。
- 71 public ActionMenuPresenter(Context context) {
- 72 super(context, com.android.internal.R.layout.action_menu_layout,
- 73 com.android.internal.R.layout.action_menu_item_layout);
- 74 }
- 145 @Override
- 146 public MenuView getMenuView(ViewGroup root) {
- 147 MenuView result = super.getMenuView(root);
- 148 ((ActionMenuView) result).setPresenter(this);
- 149 return result;
- 150 }
つまり、com.android.internal.R.layout.action_menu_item_layout がメニューのレイアウトになります。
このレイアウトのルートは com.android.internal.view.menu.ActionItemMenuView になっています。
この ActionItemMenuView の updateTextButtonVisibility() メソッドで文字列の表示/非表示をセットしています。
- 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 }
ここを見ると、文字列が表示される条件は
・文字列が空ではない
+
・アイコンが指定されていない
もしくは、
・文字列が空ではない
+
・android:showAsAction に withText がセットされている
+
・mAllowTextWithIcon もしくは mExpandedFormat が true
であることがわかります。
ハンドセットの縦/横で文字列が出ない/出るの違いを決めているのは
・mAllowTextWithIcon もしくは mExpandedFormat が true
の部分です。
- 37 public class ActionMenuItemView extends LinearLayout
- 38 implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener,
- 39 ActionMenuView.ActionMenuChildView {
- 48 private boolean mAllowTextWithIcon;
- 50 private boolean mExpandedFormat;
まず、mExpandedFormat についてみると setExpandFormat() メソッドで外部から設定するしかありません。
- 123 public void setExpandedFormat(boolean expandedFormat) {
- 124 if (mExpandedFormat != expandedFormat) {
- 125 mExpandedFormat = expandedFormat;
- 126 if (mItemData != null) {
- 127 mItemData.actionFormatChanged();
- 128 }
- 129 }
- 130 }
しかし、このメソッドを呼んでいるところがなかったので、現状では常に boolean の初期値の false になってるようです。
次に、mAllowTextWithIcon です。
この変数には、 ActionMenuItemView のコンストラクタで、com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon の値がセットされています。
- 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 }
com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon の値がどうなっているかをみると、
res/values/config.xml
- 708 <!-- Whether action menu items should obey the "withText" showAsAction
- 709 flag. This may be set to false for situations where space is
- 710 extremely limited. -->
- 711 <bool name="config_allowActionMenuItemTextWithIcon">false</bool>
res/values-w480dp/config.xml
- 20 <bool name="config_allowActionMenuItemTextWithIcon">true</bool>
つまり、横幅が 480dp より大きい画面の向きでは mAllowTextWithIcon が true になり、Action Item にアイコン + 文字列が表示されるということでしたー。
0 件のコメント:
コメントを投稿