Android可检查菜单项

时间:2011-06-04 20:21:16

标签: android android-menu android-checkbox

我的Android应用中有以下菜单布局:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/item1" 
          android:titleCondensed="Options"
          android:title="Highlight Options" 
          android:icon="@android:drawable/ic_menu_preferences" />

   <item android:id="@+id/item2" 
         android:titleCondensed="Persist"
         android:title="Persist" 
         android:icon="@android:drawable/ic_menu_preferences" 
         android:checkable="true" />
</menu>

我的问题是,当我在Android模拟器中运行我的应用程序时,第二个菜单项似乎不是“可检查的”。关于该项目应该有绿色勾号,对吗?表明其可检查。

我做错了吗?

9 个答案:

答案 0 :(得分:77)

布局看起来正确。但您必须在代码中选中并取消选中菜单项。

来自documentation

  

选择可检查项目时,系统将调用您各自的项目选择回调方法(例如onOptionsItemSelected())。您必须在此处设置复选框的状态,因为复选框或单选按钮不会自动更改其状态。您可以使用isChecked()查询项目的当前状态(就像用户选择它之前一样),然后使用setChecked()设置已检查状态。

答案 1 :(得分:31)

item包裹在group元素中,如下所示:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="all">
        <item android:id="@+id/item1"
              android:titleCondensed="Options"
              android:title="Highlight Options"
              android:icon="@android:drawable/ic_menu_preferences">
        </item>
        <item android:id="@+id/item2"
              android:titleCondensed="Persist"
              android:title="Persist"
              android:icon="@android:drawable/ic_menu_preferences"
              android:checkable="true">
        </item>
    </group>
</menu>

来自Android docs

  

android:checkableBehavior属性接受:

     

单 - 只能检查组中的一个项目(单选按钮)

     

全部 - 可以检查所有项目(复选框)

     

无 - 没有可检查的项目

答案 2 :(得分:15)

您可以通过将actionViewClass设置为android.widget.CheckBox

等可检查小部件来创建可检查的菜单项

RES /菜单/的 menu_with_checkable_menu_item.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_favorite"
        android:checkable="true"
        android:title="@string/action_favorite"
        app:actionViewClass="android.widget.CheckBox"
        app:showAsAction="ifRoom|withText" />
</menu>

如果您将actionLayout设置为带有样式android.widget.CheckBox的布局

,您甚至可以将其设置为可检查的星标

RES /布局 /action_layout_styled_checkbox.xml

<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
    style="?android:attr/starStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

RES /菜单/的 menu_with_checkable_star_menu_item.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_favorites"
        android:checkable="true"
        android:title="@string/action_favorites"
        app:actionLayout="@layout/action_layout_styled_checkbox"
        app:showAsAction="ifRoom|withText" />
</menu>

设置值

menuItem.setChecked(true/false);

获取值

menuItem.isChecked()

将MenuItem强制转换为CheckBox

CheckBox checkBox= (CheckBox) menuItem.getActionView();

答案 3 :(得分:3)

我发现最好的解决方案是从当前的API(27-28)开始使用onOptionsItemSelected()方法。

@Data
@Entity(name = "menu_structure_tbl")
public class MenuStructureTbl {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Integer menuId;
    public String menuTitle;
    public String menuText;
    public Integer menuMotherId;
    public String createDate;
    public String updateDate;
}

我在这里花了很长时间来寻找答案。且无论出于何种原因,以上答案都无济于事(我是回头的新手,我敢肯定我可能把事情搞砸了)。 这样做可能会有更好的方法,因此欢迎提出批评意见。

答案 4 :(得分:1)

正在回答,因为这里的答案似乎很长且令人费解。.我在这里有一些确切的Kotlin代码

在顶部覆盖您的活动,并覆盖onMenuItemClick函数,具有处理按钮单击以打开菜单的功能。

具有一个数组或列表,其中包含检查值并在重新创建菜单时设置检查

注意:此代码不会使菜单保持打开状态,只能确保选中的项目保持选中状态。 我注意到有很多解决堆栈溢出问题的方法,因此,如果需要的话,请看看它们

class exampleActivity : AppCompatActivity(), PopupMenu.OnMenuItemClickListener {
   private var checkChecked = arrayListOf(false,false)
   //some code

  fun clickBTN(v: View){
        val popup = PopupMenu(this,v)
        popup.setOnMenuItemClickListener(this)
        popup.inflate(R.menu.yourmenufilename)
        //assuming you have 2 or more menu items
        popup.menu[0].isChecked = checkChecked[0]
        popup.menu[1].isChecked = checkChecked[1]
        popup.show()
  }

  override fun onMenuItemClick(item: MenuItem?): Boolean {
     when(item?.itemID){
        R.id.item0 -> {
                item.isChecked = !item.isChecked
                checkChecked[0] = item.isChecked
                return true
        }
        R.id.item1 -> {
                item.isChecked = !item.isChecked
                checkChecked[1] = item.isChecked
                return true
        }
  }
}

当然,在XML中,您应该设置按钮和菜单。一个示例菜单在这里

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/item0"
        android:title="@string/hi"
        android:checkable="true"/>
    <item android:id="@+id/item1"
        android:title="@string/yo"
        android:checkable="true"/>
</menu>

答案 5 :(得分:0)

这可能与主题有关,但我的菜单没有显示复选框。我找到了this

  

注意:图标菜单中的菜单项无法显示复选框或收音机   按钮。如果您选择使图标菜单中的项目可检查,那么   你必须通过交换图标和/或亲自指示州   每次状态在开启和关闭之间变化时都会发出文本。

答案 6 :(得分:0)

以编程方式添加菜单项

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    menu.add("Item1").setActionView(R.layout.action_layout_checkbox).setCheckable(true);
    return super.onCreateOptionsMenu(menu);
}

res / layout /action_layout_checkbox.xml

<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

答案 7 :(得分:0)

阅读此内容

如前所述,“手动检查”只是冰山一角。它以极快的速度闪烁菜单,使用户什么也看不见,而且非常直观,令人沮丧,并且非常有效。 REAL TASK(因此)允许用户记住摘要事件。

好消息:这可以完成,它确实有效,这就是您的操作方式。 @TouchBoarder最好,所以我将复制他的代码。然后开发它。

这个想法是要检测是否单击了复选框,然后(并且仅在选中该复选框时)稍微抑制菜单的删除,添加一个计时器500ms然后关闭菜单,这使复选框具有“滴答”动画时间运行并创建正确的“感觉”

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_favorite"
        android:checkable="true"
        android:title="@string/action_favorite"
        app:actionViewClass="android.widget.CheckBox"
        app:showAsAction="ifRoom|withText" />
</menu>

然后您照常进行此方法,但请确保添加所有这些多余的凸起物

public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the bottom bar and the top bar (weird)
    BottomAppBar bottomBar = findViewById(R.id.bottom_app_bar_help);
    Menu bottomMenu = bottomBar.getMenu();
    getMenuInflater().inflate(R.menu.bottom_nav_menu, bottomMenu);
    for (int i = 0; i < bottomMenu.size(); i++) {
        bottomMenu.getItem(i).setOnMenuItemClickListener(item -> {
            if (item.getItemId()==R.id.action_favorite){
                item.setChecked(!item.isChecked());
                // Keep the popup menu open
                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
                item.setActionView(new View(frmMain.this));
                item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
                    @Override
                    public boolean onMenuItemActionExpand(MenuItem item) {
                        final Handler handler = new Handler();
                        handler.postDelayed(() -> bottomMenu.close(), 500);
                        return false;
                    }

                    @Override
                    public boolean onMenuItemActionCollapse(MenuItem item) {
                        final Handler handler = new Handler();
                        handler.postDelayed(() -> bottomMenu.close(), 500);
                        return false;
                    }
                });
                return false;
            }
            else {
                return onOptionsItemSelected(item);
            }
        });
    }
    return true;
}

其他菜单事件在这里

public boolean onOptionsItemSelected(MenuItem item) {
    // Bottom Bar item click
    try {
        switch (item.getItemId()) {
            case R.id.mnuExit:
                MenuClick(ClickType.LOGOUT);
                return true;

            case R.id.mnuList:
                MenuClick(ClickType.LIST);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return super.onOptionsItemSelected(item);
}

答案 8 :(得分:0)

我在菜单中有两项,并在menu.xml文件中设置为可检查,如下所示:

    <item
        android:id="@+id/A"
        android:title="A"
        app:showAsAction="never"
        android:checkable="true"/>
    <item
        android:id="@+id/B"
        android:title="B"
        app:showAsAction="never"
        android:checkable="true"/> 

和下面的菜单复选框逻辑。

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {

    switch (item.getItemId()) {
        case R.id.A:
           //logic goes here


            if(item.isChecked())
            {
             //logic is it is checked
             item.setChecked(false);
            }
            else
            {
               //logic is it is not checked
                item.setChecked(true);
            }
            return true;
        case R.id.B:
         //logic for second checkbox goes here


            if(item.isChecked())
            {
             //logic is it is checked
                item.setChecked(false);
            }
            else
            {
             //logic is it is not checked
                item.setChecked(true);
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }