工具栏不会在操作模式下消失

Toolbar won't disappear in action mode

我正在尝试实现以下功能:当我长按列表项时,将启动操作模式,并且可以删除一个或多个项目。
我从 DocumentsActivity 搜索开始,该搜索会启动带有 ListView 及其项目的片段 DocumentsFragment。 ListAdapter 是通过Fragment 的onCreate 中的方法调用setListAdapter(this.documentsAdapter) 来初始化和设置的。我在 Fragment:

onActivityCreated 中的列表视图上设置了各种侦听器
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);
}

当长按列表项时,动作模式开始,菜单 documents_context_menu 显示为动作栏。但问题是,操作栏出现在工具栏上方,工具栏不会消失(见图片)。

我试过调用 getSupportActionBar().hide() 或将其设置为空,甚至使用另一个 style/theme。这一切都没有用。有时蓝色工具栏是完全白色的,但仅此而已。

我完全不知道为什么工具栏不会消失。可以给点建议吗?

提前致谢!

_____ 更新 1 _____

这是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>

这就是在 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();
    }
}

正如评论中提供的 link 所指出的,您只需在 AppTheme 样式中添加以下行:

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

只是表示动作模式应该覆盖window内容而不是将其向下推,它告诉你不需要为动作模式保留任何space。

添加:

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

或者:

//Remove selected selections
public void removeSelection() {

    mSelectedItemsIds = new SparseBooleanArray();
}

据我浏览你的代码并理解它,你已经完成了你提供的工具栏作为 ActionBar 并使用 .NoActionBar 主题的所有内容,除了根据 Android 开发人员你还应该设置windowActionBar 属性在您的样式中设置为 false。 enter link description here 第二段清除它。

希望对您有所帮助!

所有这些答案都很好你应该尝试它们但你需要的是 ContextualMenu 所以你应该首先将视图添加到 registerForContextMenu() 这样菜单就知道哪些菜单是上下文的然后实现 onCreateContextMenu 你的 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);
}

然后像这样实现 onContextItemSelected() :

@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);
}
}

然后您必须对视图执行操作并实施 AbsListView.MultiChoiceModeListener 然后使用 CHOICE_MODE_MULTIPLE_MODAL 参数调用 setChoiceMode()。像这样:

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;
}
});

我所说的所有内容以及更多内容,您可以在 this android developer documentation

中找到

实际上这个问题是由不同的事情引起的。 首先,windowActionBar设置了true,还有属性fitsSystemWindows.我在styles.xml.[=20=中删除了两行]

然后在activity布局里有属性layout_marginTop="?actionBarSize"我没看到,一头雾水跟着。但是这个属性需要存在,所以当调用 onCreateActionModeonDestroyActionMode 时,我在方法 onActivityCreated 中处理它。

在那之后,我遇到了列表视图项目消失的自动问题。我通过在 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);
}

在 Kotlin 中,假设您的 Activity 扩展自 AppCompatActivity

  • 您应该获取支持操作栏的实例并调用方法

    supportActionBar?.show()supportActionBar?.hide()

  • 如果您使用的是片段,则可以从片段的 activity 实例

    访问操作栏

    (activity as AppCompatActivity).supportActionBar?.show()