Android将菜单项对齐到操作栏中的左侧

时间:2012-10-17 16:36:55

标签: android android-actionbar android-menu

我的应用程序中有操作栏,显示我res/menu/activity_main.xml

中定义的菜单项

我的菜单项在操作栏上右对齐。我希望它们与左边对齐。

我找到的只有这个二手自定义操作栏的解决方案,如下所示: Positioning menu items to the left of the ActionBar in Honeycomb

但是,我不想为我的菜单创建自定义布局。我想使用从res/menu/activity_main.xml生成的默认菜单项。

这可能吗?

2 个答案:

答案 0 :(得分:4)

好吧,我对此感到好奇,所以我深入挖掘了SDK的源代码。我在AppCompatActivity中使用了3个菜单项的XML文件,我使用了默认的onCreateOptionMenu方法,即:

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

在我使用调试器的inflate方法继续之后,我经历了以下堆栈:

updateMenuView():96, BaseMenuPresenter (android.support.v7.internal.view.menu)
updateMenuView():231, ActionMenuPresenter (android.support.v7.widget)
dispatchPresenterUpdate():284, MenuBuilder (android.support.v7.internal.view.menu)
onItemsChanged():1030, MenuBuilder (android.support.v7.internal.view.menu)
startDispatchingItemsChanged():1053, MenuBuilder (android.support.v7.internal.view.menu)
preparePanel():1303, AppCompatDelegateImplV7 (android.support.v7.app)
doInvalidatePanelMenu():1541, AppCompatDelegateImplV7 (android.support.v7.app)
access$100():92, AppCompatDelegateImplV7 (android.support.v7.app)
run():130, AppCompatDelegateImplV7$1 (android.support.v7.app)
handleCallback():739, Handler (android.os)
dispatchMessage():95, Handler (android.os)
loop():148, Looper (android.os)
main():5417, ActivityThread (android.app)
invoke():-1, Method (java.lang.reflect)
run():726, ZygoteInit$MethodAndArgsCaller (com.android.internal.os)
main():616, ZygoteInit (com.android.internal.os)

BaseMenuPresenter的{​​{1}}方式结束,这就是完成工作的地方。

方法代码:

updateMenuView

此处, public void updateMenuView(boolean cleared) { final ViewGroup parent = (ViewGroup) mMenuView; if (parent == null) return; int childIndex = 0; if (mMenu != null) { mMenu.flagActionItems(); ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems(); final int itemCount = visibleItems.size(); for (int i = 0; i < itemCount; i++) { MenuItemImpl item = visibleItems.get(i); if (shouldIncludeItem(childIndex, item)) { final View convertView = parent.getChildAt(childIndex); final MenuItemImpl oldItem = convertView instanceof MenuView.ItemView ? ((MenuView.ItemView) convertView).getItemData() : null; final View itemView = getItemView(item, convertView, parent); if (item != oldItem) { // Don't let old states linger with new data. itemView.setPressed(false); ViewCompat.jumpDrawablesToCurrentState(itemView); } if (itemView != convertView) { addItemView(itemView, childIndex); } childIndex++; } } } // Remove leftover views. while (childIndex < parent.getChildCount()) { if (!filterLeftoverView(parent, childIndex)) { childIndex++; } } } getItemView方法执行其姓名所说的内容。第一个膨胀一个新视图,第二个将它添加到父视图。更重要的是,在调试器下可以检查父对象,它是ActionMenuView,它继承自addItemView和夸大的形式abc_action_menu_layout.xml

这意味着如果您可以获得此视图,则可以执行您想要的操作。从理论上讲,我认为可以通过大量反思来完成,但这会很痛苦。 而不是那样,您可以在代码中重现它。可以找到实现here

根据上述事项,您的问题的答案是肯定的,可以做到,但这将是棘手的。

修改

我用反射创建了一个概念验证。我使用了LinearLayout

我已经在模拟器(Android 6.0)和我的Zuk Z1(CM Android 5.1.1)上尝试了这一点,两者都运行良好。

菜单XML:

com.android.support:appcompat-v7:23.1.0

Activty XML:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/action_settings" android:title="@string/action_settings"
        android:orderInCategory="100" app:showAsAction="always" />
    <item android:id="@+id/action_settings2" android:title="TEST1"
        android:orderInCategory="100" app:showAsAction="always" />
    <item android:id="@+id/action_settings3" android:title="TEST2"
        android:orderInCategory="100" app:showAsAction="always" />
</menu>

的活动:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button"
        android:layout_gravity="center_vertical" />
</LinearLayout>

虽然这里的重力发生了变化,但在屏幕上并没有任何明显的差异。为了获得真正的可见变化,应调整其他布局参数(例如宽度)。

总而言之,自定义布局更容易使用。

答案 1 :(得分:0)

你可以这样做:

activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
            ActionBar.DISPLAY_SHOW_CUSTOM);
activity.getActionBar().setCustomView(mAutoSyncSwitch, new ActionBar.LayoutParams(
            ActionBar.LayoutParams.WRAP_CONTENT,
            ActionBar.LayoutParams.WRAP_CONTENT,
            Gravity.CENTER_VERTICAL | Gravity.LEFT));