2011-11-16 79 views
13

所以我试图让我的菜单项,这是在操作栏上显示行为像一个可检查的菜单选项。第一部分的作品,这意味着它是可检查的,当我按下它,并在代码中setChecked(true)它的工作。但不起作用的是视觉部分。菜单项在检查和未检查状态下在操作栏上的显示方式没有变化?我尝试过使用invalidateOptionsMenu(),但那不做这项工作,不仅如此,在我的代码中的那一行,我无法离开检查状态?!? 会发生什么是无效OptionsMenu()接缝来取消选中的状态,并最终'循环',或每当按下该菜单项我继续去检查代码的未检查的部分,它被检查和无效它得到选中我猜...Android操作栏可检查菜单项无法正常工作/显示?

这是从我的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); 
} 

谢谢!

回答

30

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

您正在使用它们作为主菜单项,因此它不起作用。

消息来源:下载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

+0

那是哪里引述? –

+0

您可以在Api演示中找到注释:ApiDemos \ res \ menu \ checkable.xml,我无法在开发人员文档中找到它 – Entreco

4

最好的解决办法是将<Item>actionLayout设置为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" 
    /> 
  • 设置你的<Item>这样。请注意,你需要它显示在子菜单中的情况下,CheckableChecked仍然(在这种情况下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> 
    
  • 在你代码,当菜单被创建时,我们需要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

    什么是mRetainedFragment? –

    +0

    这就是我想要的代码。将其替换为您希望代码在切换复选框时执行的任何操作。 – Timmmm

    +0

    谢谢。我已通过在操作栏中添加自定义布局进行了修复。完美的工作 –

    5

    或者只是做自己

    @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(); 
    
    +0

    如果可以的话,我会投票给你一千次 – Rasel