Android 操作栏可检查菜单项无法正常工作/显示?

问题描述 投票:0回答:4

所以我试图让我的菜单项显示在操作栏上,使其表现得像一个可检查的菜单选项。第一部分起作用,这意味着它是可检查的,当我按下它并在代码中设置 setChecked(true) 时它起作用。但不起作用的是视觉部分。在选中和未选中状态下,菜单项在操作栏上的外观没有变化吗?我尝试使用 invalidateOptionsMenu() 但这并不能完成这项工作,不仅如此,在我的代码中使用该行我无法退出检查状态?!? 发生的情况是, invalidate OptionsMenu() 接缝取消了选中状态,并且我最终“循环”,或者每次按下该菜单项时,我都会继续转到代码的未选中部分,在该部分进行检查,并且使用 invalidate 时,它会被取消选中我猜...

这是我的菜单 XML 文件中的代码:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/lenslist_menu_add"
        android:showAsAction="always"
        android:title="@string/add"/>
    <item android:id="@+id/lenslist_menu_delete"
        android:showAsAction="always"
        android:checkable="true"
        android:title="@string/delete"/>
</menu>

这是java代码:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    switch (item.getItemId()) {
    case R.id.lenslist_menu_add:

        return true;
    case R.id.lenslist_menu_delete:
        if (item.isChecked() == true) {
            item.setChecked(false);
            deleteMode = false;
            lensAdapter.setDeleteMode(false);
        } else {
            item.setChecked(true);
            deleteMode = true;
            lensAdapter.setDeleteMode(true);
        }
        lensAdapter.notifyDataSetChanged();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

谢谢!

android menu android-actionbar
4个回答
33
投票

可检查的项目仅出现在子菜单或上下文菜单中。

您将它们用作主菜单项,因此它将不起作用。

来源: 下载 API DEMOS,然后打开文件 ApiDemos/res/menu/checkable.xml,您将在第 13 行看到它作为注释。我不知道为什么他们在开发者文档

带评论的参考: http://alvinalexander.com/java/jwarehouse/android-examples/platforms/android-2/samples/ApiDemos/res/menu/checkable.xml.shtml


9
投票

或者自己做

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    menu.findItem(R.id.item1).setIcon(menu_checked?R.drawable.menu_ico_checked:R.drawable.menu_ico_unchecked);
    return super.onPrepareOptionsMenu(menu);
}

并在 onOptionsItemSelected 中执行以下操作:

 ....
 menu_checked=!menu_checked;
 invalidateOptionsMenu();

4
投票

最好的解决方案是将

actionLayout
<Item>
设置为
CheckBox
。该解决方案为您提供了一个原生外观的复选框(带有材质动画等),其字体与其他项目相匹配,并且它既可以作为操作,也可以在子菜单中使用。

  1. 创建一个名为
    action_checkbox.html
    的新布局:
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:paddingStart="8dp"
          android:paddingEnd="8dp"
          android:checked="false"
          android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Menu"
          android:id="@+id/action_item_checkbox"
    />
  1. 像这样设置你的
    <Item>
    。请注意,您仍然需要
    Checkable
    Checked
    ,以防它显示在子菜单中(在这种情况下,
    actionLayout
    将被忽略。
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
    <item android:id="@+id/menu_action_logging"
          android:title="@string/action_logging"
          android:orderInCategory="100"
          android:showAsAction="always"
          android:checkable="true"
          android:checked="false"
          android:actionLayout="@layout/action_checkbox"
        />
</menu>
  1. 在您的代码中,创建菜单时,我们需要a)设置复选框的标题以匹配菜单项标题,b)恢复菜单可选项和额外复选框的选中状态,c)添加一个onClicked() 监听器用于我们的额外复选框。在此代码中,我将复选框的状态保留在
    RetainedFragment
    中。
    // Set the check state of an actionbar item that has its actionLayout set to a layout
    // containing a checkbox with the ID action_item_checkbox.
    private void setActionBarCheckboxChecked(MenuItem it, boolean checked)
    {
        if (it == null)
            return;

        it.setChecked(checked);

        // Since it is shown as an action, and not in the sub-menu we have to manually set the icon too.
        CheckBox cb = (CheckBox)it.getActionView().findViewById(R.id.action_item_checkbox);
        if (cb != null)
            cb.setChecked(checked);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
    {
        inflater.inflate(R.menu.menu_main, menu);
        super.onCreateOptionsMenu(menu, inflater);

        // Restore the check state e.g. if the device has been rotated.
        final MenuItem logItem = menu.findItem(R.id.menu_action_logging);
        setActionBarCheckboxChecked(logItem, mRetainedFragment.getLoggingEnabled());

        CheckBox cb = (CheckBox)logItem.getActionView().findViewById(R.id.action_item_checkbox);
        if (cb != null)
        {
            // Set the text to match the item.
            cb.setText(logItem.getTitle());
            // Add the onClickListener because the CheckBox doesn't automatically trigger onOptionsItemSelected.
            cb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onOptionsItemSelected(logItem);
                }
            });
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_action_logging:
                // Toggle the checkbox.
                setActionBarCheckboxChecked(item, !item.isChecked());

                // Do whatever you want to do when the checkbox is changed.
                mRetainedFragment.setLoggingEnabled(item.isChecked());
                return true;
            default:
                break;
        }

        return false;
    }

0
投票

虽然其他解决方案也可能有效,但我认为自己实现切换的小代码就可以了:

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

    <item
        android:id="@+id/menuItemToTest" android:checkable="true"
        android:showAsAction="never"
        android:title="@string/some_text" />
</menu>

代码:

val menuItem= ...findItem(R.id.menuItemToTest)
menuItem.setOnMenuItemClickListener {
    menuItem.isChecked=!menuItem.isChecked
    true
}

如果需要,请记住还要在已保存状态下保存和恢复。

© www.soinside.com 2019 - 2024. All rights reserved.