Search code examples
androidandroid-recyclerviewtoolbarandroid-cardviewcontextual-action-bar

Contextual Action Bar - action bar added above existing action bar (two action bars)


I have a RecyclerView which holds multiple CardView's and when a user long clicks a CardView, a Contextual Action Bar is shown with "delete" option.

I used the recyclerview-multiselect library to do this, and followed the tutorial.

VideosAdapter:

public class VideosAdapter extends RecyclerView.Adapter<VideosAdapter.MyViewHolder> {

    private Context context;
    private List<VideoItem> videoList;
    private ModalMultiSelectorCallback mActionModeCallback;
    private MultiSelector mMultiSelector;

    public VideosAdapter(Context context, List<VideoItem> videoList, ModalMultiSelectorCallback mActionModeCallback, MultiSelector mMultiSelector) {
        this.context = context;
        this.videoList = videoList;
        this.mActionModeCallback = mActionModeCallback;
        this.mMultiSelector = mMultiSelector;
    }


    public class MyViewHolder extends SwappingHolder
            implements View.OnLongClickListener, View.OnClickListener {
        public ImageView thumbnail;
        private MultiSelector mMultiSelector;

        public MyViewHolder(View itemView, MultiSelector mMultiSelector) {
            super(itemView, mMultiSelector);
            this.mMultiSelector = mMultiSelector;
            itemView.setLongClickable(true);
            thumbnail = (ImageView) itemView.findViewById(R.id.thumbnail);
            setSelectionModeBackgroundDrawable(ResourcesCompat.getDrawable(context.getResources(), R.drawable.background_activated, null));
            thumbnail.setOnLongClickListener(this);
            thumbnail.setOnClickListener(this);
        }


        @Override
        public boolean onLongClick(View view) {
            if (!mMultiSelector.isSelectable()) {
                ((AppCompatActivity) context).startSupportActionMode(mActionModeCallback);
                mMultiSelector.setSelectable(true);
                mMultiSelector.setSelected(MyViewHolder.this, true);
                return true;
            }
            return false;
        }

        @Override
        public void onClick(View view) {
            if (mMultiSelector.tapSelection(this)) {
                // Selection is on, so tapSelection() toggled item selection.
            } else {
                // Selection is off; handle normal item click here.
            }
        }
    }


    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.video_card, parent, false);

        return new MyViewHolder(itemView, mMultiSelector);
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        VideoItem video = videoList.get(position);
        // loading album cover using Glide library
        Glide.with(context).load(video.getThumbnail()).into(holder.thumbnail);
    }


    @Override
    public int getItemCount() {
        return videoList.size();
    }
}

And GalleryFragment:

public class GalleryFragment extends Fragment {

    private RecyclerView recyclerView;
    private VideosAdapter adapter;
    private List<VideoItem> videoList;

    private MultiSelector mMultiSelector = new MultiSelector();
    private ModalMultiSelectorCallback mActionModeCallback
            = new ModalMultiSelectorCallback(mMultiSelector) {

        @Override
        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            super.onCreateActionMode(actionMode, menu);
            getActivity().getMenuInflater().inflate(R.menu.toolbar_delete_manu, menu);
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
            if (menuItem.getItemId() == R.id.toolbar_item_delete) {
                actionMode.finish();

                for (int i = videoList.size(); i >= 0; i--) {
                    if (mMultiSelector.isSelected(i, 0)) {
                        // remove item from list
                        recyclerView.getAdapter().notifyItemRemoved(i);
                    }
                }

                mMultiSelector.clearSelections();
                return true;

            }
            return false;
        }
    };



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_gallery, container, false);

        recyclerView = (RecyclerView) root.findViewById(R.id.recycler_view);

        videoList = new ArrayList<>();
        adapter = new VideosAdapter(getActivity(), videoList, mActionModeCallback, mMultiSelector);

        recyclerView.setAdapter(adapter);

        prepareVideos(); // getting videos objects for the adapter
        return root;
    }
}

The problem I have is - when I select a CardView, what should happen it that the new menu/toolbar (toolbar_delete_manu.xml) is shown over/instead of the current menu/toolbar.

In reality what happens looks like this:

enter image description here

The contextual toolbar goes over the existing one.

How can I fix it? I want it to go instead.


Solution

  • Just add <item name="android:windowActionModeOverlay">true</item> to your AppTheme/Style