Toolbar won't disappear in action mode

2019-06-22 04:55发布

I am trying to implement the feature that, when I am long clicking a list item, the action mode shall start and it shall be possible to delete one or more items.
I am starting in the MainActivity DocumentsActivity a search, which starts a Fragment DocumentsFragment with the ListView and their items. The ListAdapter is initialized and set via method call setListAdapter(this.documentsAdapter) in the onCreate in the Fragment. I set various listeners on the listview in the onActivityCreated in the Fragment:

public void onActivityCreated(Bundle savedInstanceState) {

    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            getListView().setItemChecked(position, true);
            return true; 
    }});
    getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            menu.clear();
            ((DocumentsActivity)getActivity()).getMenuInflater().inflate(R.menu.documents_context_menu, menu);
            return true;
        }
    });
    super.onActivityCreated(savedInstanceState);
}

When I long click on a listitem the action mode gets started and the menu documents_context_menu appears to be the action bar. But the problem is, the action bar appears above the toolbar and the toolbar won't disappear (see the picture).

I've tried to call getSupportActionBar().hide() or set it to null or even use another style/theme. It all didn't work. Sometimes the blue toolbar was completely white, but that is all.

I have absolutely no idea why the toolbar won't disappear. May you give some advice?

Thanks in advance!

_____ Update 1 _____

This is the styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:fitsSystemWindows">true</item>
    <item name="colorAccent">@color/darkblue100</item>
    <item name="android:actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
    <item name="actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
    <item name="android:actionMenuTextColor">@color/black</item>
</style>

And this is how the action bar is set in the Activity:

protected void onCreate(Bundle savedInstanceState) {
    handleIntent(getIntent());
    requestWindowFeature(5);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_documents);
    Toolbar mToolbar = (Toolbar) findViewById(R.id.tool_bar);
    setSupportActionBar(mToolbar);
    args = getIntent().getExtras();
    if (findViewById(R.id.container_documents) != null && savedInstanceState == null) {
        showDocumentsFragment();
    }
}

5条回答
我命由我不由天
2楼-- · 2019-06-22 05:29

all of this answers are fine you should try them but what you need is a ContextualMenu so you should first add views to a registerForContextMenu() so menu knows which menus are contextual then implement the onCreateContextMenu of your Activity

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
                            ContextMenuInfo menuInfo) {
   super.onCreateContextMenu(menu, v, menuInfo);
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.context_menu, menu);
}

then implement onContextItemSelected() like this :

@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
    case R.id.edit:
        editNote(info.id);
        return true;
    case R.id.delete:
        deleteNote(info.id);
        return true;
    default:
        return super.onContextItemSelected(item);
}
}

then you have to perform an action on views and implement AbsListView.MultiChoiceModeListener then call setChoiceMode() with the CHOICE_MODE_MULTIPLE_MODAL argument. like this :

ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

@Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
                                      long id, boolean checked) {
    // Here you can do something when items are selected/de-selected,
    // such as update the title in the CAB
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    // Respond to clicks on the actions in the CAB
    switch (item.getItemId()) {
        case R.id.menu_delete:
            deleteSelectedItems();
            mode.finish(); // Action picked, so close the CAB
            return true;
        default:
            return false;
    }
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    // Inflate the menu for the CAB
    MenuInflater inflater = mode.getMenuInflater();
    inflater.inflate(R.menu.context, menu);
    return true;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
    // Here you can make any necessary updates to the activity when
    // the CAB is removed. By default, selected items are deselected/unchecked.
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    // Here you can perform updates to the CAB due to
    // an <code><a href="/reference/android   /view/ActionMode.html#invalidate()">invalidate()</a></code> request
    return false;
}
});

all of what i said and ultimately more, you can find in this android developer documentation

查看更多
我只想做你的唯一
3楼-- · 2019-06-22 05:33

As pointed out in the link provided in comments you just need to add following line to your AppTheme style:

<item name="windowActionModeOverlay">true</item>

It just indicates that action mode should overlay window content instead of pushing it down,it tells that you don't need any reserved space for action mode.

查看更多
▲ chillily
4楼-- · 2019-06-22 05:37

Actually the was caused by different settings. First, as multiple times said, the windowActionBar was set true, also was the attribute fitsSystemWindows.I deleted both lines in styles.xml.

Then there was in the activity layout the attribute layout_marginTop="?actionBarSize" I didn't see, following in complete confusion. But this attribute needs to be there so I am handling it in the method onActivityCreated when onCreateActionMode and onDestroyActionMode are called.

After that all I had the automagically problem that the listview items disappeared. I fixed it by commiting my fragment again in onDestroyActionMode.

public void onActivityCreated(Bundle savedInstanceState) {

    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {...}
    });
    getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
        LinearLayout ll = ((DocumentsActivity)getActivity()).findViewById(R.id.container_documents);

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
            params.setMargins(0, 0, 0, 0);
            ll.setLayoutParams(params);

            ((DocumentsActivity)getActivity()).getSupportActionBar().hide();
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.documents_context_menu, menu);
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
            params.setMargins(0, R.attr.actionBarSize, 0, 0);
            ll.setLayoutParams(params);
            ((DocumentsActivity)getActivity()).getSupportActionBar().show();

            if (getFragmentManager() != null)
                getFragmentManager()
                .beginTransaction()
                .detach(this)
                .attach(this)
                .commit();
        }
    });

    super.onActivityCreated(savedInstanceState);
}
查看更多
我只想做你的唯一
5楼-- · 2019-06-22 05:42

Add:

 //Set action mode null after use
    public void setNullToActionMode() {
        if (mActionMode != null)
            mActionMode = null;
    }

Or:

//Remove selected selections
public void removeSelection() {

    mSelectedItemsIds = new SparseBooleanArray();
}
查看更多
趁早两清
6楼-- · 2019-06-22 05:50

Well as far as i go through your code and understand it, you have done everything that you provided your Toolbar to act as ActionBar and used .NoActionBar theme except according to Android Developer you should also set the windowActionBar attribute to false in your style. enter link description here Second para clears it out.

I hope it helps!

查看更多
登录 后发表回答