Can't display sub-menu for custom ActionProvid

2019-04-02 09:33发布

I've created a custom ActionProvider that I want to use to show a sub-menu for sorting, similar visually to ShareActionProvider. The action view displays as expected, but clicking on the icon doesn't display the sub-menu or show any visual feedback (pressed state) at all. I'm using the support v7 library for backward compatibility action bar. Is there an implementation I am missing to display the menu?

ActionProvider:

public class SortActionProvider extends ActionProvider implements OnMenuItemClickListener {

    private Context mContext;

    public SortActionProvider(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    public View onCreateActionView(){
        ImageView imageView = new ImageView(mContext);
        imageView.setImageResource(R.drawable.ic_action_sort_by_size);

        return imageView;
    }

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

    @Override
    public void onPrepareSubMenu(SubMenu subMenu){
        subMenu.clear();

        subMenu.add("Sort by name").setOnMenuItemClickListener(this);
        subMenu.add("Sort by type").setOnMenuItemClickListener(this);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item){
        Toast.makeText(mContext, "I was clicked!", Toast.LENGTH_SHORT).show();
        return true;
    }
}

Menu:

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

    <item
        android:id="@+id/menu_sort"
        android:actionProviderClass="com.myapp.provider.SortActionProvider"
        android:showAsAction="always"
        android:title="@string/sort"
        support:actionProviderClass="com.myapp.provider.SortActionProvider"
        support:showAsAction="always"/>

</menu>

2条回答
闹够了就滚
2楼-- · 2019-04-02 10:15

Unfortunately, onPrepareSubMenu() is only called when onCreateActionView() returns null. Your solution (attaching a PopupMenu to the ImageView) will work, but since your ImageView is displaying an icon, you might consider just setting the icon in the menu XML and getting rid of the ImageView:

<item android:id="@+id/menu_sort"
      android:icon="@drawable/ic_action_sort_by_size"
      android:title="@string/sort"
      support:actionProviderClass="com.myapp.provider.SortActionProvider"
      support:showAsAction="always" />

and then:

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

This should also solve the problem with no visual feedback for touch states - the problem being that your ImageView is not configured to do anything with touch states.

查看更多
手持菜刀,她持情操
3楼-- · 2019-04-02 10:24

The ActionProvider doesn't show the sub-menu when you click on the action view. I'm actually not sure under what conditions the sub-menu is displayed. What I had to do was attach a PopupMenu to the action view:

@Override
public View onCreateActionView(){
    ImageView imageView = new ImageView(mContext);
    imageView.setImageResource(R.drawable.ic_action_sort_by_size);

    final PopupMenu menu = new PopupMenu(mContext, imageView);
    menu.inflate(R.menu.sort_options_menu);
    menu.setOnMenuItemClickListener(this);

    imageView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v){
            menu.show();
        }
    });

    return imageView;
}
查看更多
登录 后发表回答