Actionbar实现子菜单的几种方式

第一种方式是使用ActionProvider。定义一个如下代码的ActionBar

public class PopupMenuActionProvider extends ActionProvider {

    public PopupMenuActionProvider(Context context) {
        super(context);
    }

    @Override
    public void onPrepareSubMenu(SubMenu subMenu) {
        subMenu.clear();
        subMenu.add(0, 0, 0, "Sub1");
        subMenu.add(0, 1, 1, "Sub2");
    }

    @Override
    public View onCreateActionView() {
        return null;
    }

    @Override
    public boolean hasSubMenu() {
        return true;
    }
}

然后在activity的menu.xml中item的android:actionProviderClass使用该PopupMenuActionProvider即可。

第二种方式仍然是使用ActionProvider,不过此时是不使用onPrepareSubMenu,而是直接在onCreateActionView中定义。拷贝自别人的blog

public class MyActionProvider extends ActionProvider{
    private ContextWrapper mContextWrapper;
    private OnMenuItemClickListener mOnMenuItemClickListener;
    
    public MyActionProvider(Context context) {
        super(context);
        mContextWrapper = (ContextWrapper)context;
    }

    @Override
    public View onCreateActionView() {
        LayoutInflater layoutInflater = LayoutInflater.from(mContextWrapper);
        View view = layoutInflater.inflate(R.layout.my_action_provider, null);
        ImageView popupView = (ImageView)view.findViewById(R.id.popup_view);
        popupView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPopup(v);
            }
        });
        mOnMenuItemClickListener = new OnMenuItemClickListener() {
            private String TAG = "mOnMenuItemClickListener";

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                case R.id.Settings1:
                    Log.v(TAG , "Settings1");
                    break;
                case R.id.Settings2:
                    Log.v(TAG , "Settings2");
                    break;

                default:
                    break;
                }
                return false;
            }
        };
        return view;
    }

    private void showPopup(View v) {
        PopupMenu popup = new PopupMenu(mContextWrapper, v);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.popmenu, popup.getMenu());
        popup.setOnMenuItemClickListener(mOnMenuItemClickListener);
        popup.show();
    }

}

这里是在layout中定义一个imageview,然后在onclick的时候现实一个PopupMenu。

第三种方式是在activty/fragment的onOptionsItemSelected响应对一个item的点击,然后创建popupmenu。好处是比第二种方式不用多创建一个类,坏处是代码偶耦合在activity/fragment中。

以上两种方式是子菜单的表现方式,后面的是使用spinner这种类似于子菜单的方式。

第四种方法是使用ActionBar.SetNavigationMode(NAVIGATION_MODE_LIST)。这其实是利用了ActionBar本身可以使用spinner这种drop down list来切换的功能。参考Android actionbar 文档

第五种方法是自己指定一个item的类为spinner,例如定义menu.xml为

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" >

    <item
        android:id="@+id/action_spinner"
        android:actionViewClass="android.widget.Spinner"        android:orderInCategory="1"
        android:showAsAction="always"/>
</menu>

然后在代码中添加spinner的内容。

第六种方式类似,只是不使用android:actionViewClass而是使用android:actionLayout,在layout.xml中指定使用spinner。

总结下,其实这些方式利用了actionbar的几个功能:

  • 设置NavigationMode为mode_list来利用actionbar自带的spinner形式的droplist。
  • 设置actionview为spinner或其他view
  • 使用actionprovider来进一步完全掌控一个menu item的具体行为。
原文地址:https://www.cnblogs.com/xichengtie/p/4236940.html