<?xml version="1.0" encoding="UTF-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/select_options" android:title="Add/Remove"> <menu> <group android:checkableBehavior="all"> <item android:id="@+id/A" android:checked="true" android:title="Option One" /> <item android:id="@+id/B" android:checked="true" android:title="Option Two" /> </group> </menu> </item> </menu>
和
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.selection_menu,menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item){ switch (item.getItemId()){ case R.id.A: item.setChecked(!item.isChecked()); return true; case R.id.B: item.setChecked(!item.isChecked()); return true; default: return super.onOptionsItemSelected(item); } }
解决方法
老实说,我不知道你所追求的是否可行(编辑:你正在实施它的方式,作为一个子菜单),但我会这样做:
它可能看起来有点复杂,但它是直接的,并且以这种方式,如果您选择/取消选择项目,它将不会消失,并且您可以实现更多功能.
以下是我亲自完成的工作:
>创建一个表示子菜单项的类.它应该包含一个字符串(描述)和一个布尔值(如果选中或不存储则存储).
public class SettingCheckBox implements Serializable { private static final long serialVersionUID = 1L; private static final String DEFAULT_DESCRIPTION = "N/A"; private final String description; private boolean checked; public String getDescription () { return description == null ? DEFAULT_DESCRIPTION : description; } public void setChecked ( final boolean checked ) { this.checked = checked; } public boolean getChecked () { return checked; } public SettingCheckBox ( final String description ) { this.description = description; } }
如您所见,该类实现了Serializable,以便可以使用Intents / bundles将该类的对象从一个活动传递到另一个.
>将以下内容添加到当前活动中(我假设它名为MainActivity,因此在您尝试时,请使用您的活动名称替换MainActivity).
public static final String SETTING_CHECK_Box = "SETTING_CHECK_Box"; private ArrayList < SettingCheckBox > settingList; @Override public void onCreate(Bundle savedInstanceState) { // ... settingList = new ArrayList < SettingCheckBox > (); settingList.add ( new SettingCheckBox ( "Option A" ) ); settingList.add ( new SettingCheckBox ( "Option B" ) ); // ... add more items // restore any prevIoUsly saved list if ( savedInstanceState != null ) { settingList = (ArrayList < SettingCheckBox >) savedInstanceState.getSerializable ( SETTING_CHECK_Box ); } // ... } protected void onSaveInstanceState ( Bundle outState ) { super.onSaveInstanceState ( outState ); outState.putSerializable ( SETTING_CHECK_Box,settingList ); }
列表(ArrayList)用于通过复选框托管所有设置子菜单项.
如您所见,每个SettingCheckBox对象都有描述和状态(已选中或未选中).默认情况下,一旦创建,则取消选中对象状态.
您应该初始化onCreate方法中的列表.
静态和最终变量SETTING_CHECK_Box用作在活动重新创建之前/之后(如屏幕旋转)保存/恢复该列表内容的键,还用于将设置列表从活动传递到另一个活动. (稍后解释)
<?xml version="1.0" encoding="UTF-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/select_options" android:title="Add/Remove"> </item> </menu>
不再需要子菜单,因为您将实现一个类似于一个的活动.
现在,要将菜单项链接到将显示设置的活动,您应该在当前活动中使用onOptionsItemSelected方法,如下所示:
@Override public boolean onOptionsItemSelected ( MenuItem menuItem ) { if ( menuItem.getItemId () == R.id.select_options ) { Intent intent = new Intent ( this,MyActivity_Settings.class ); intent.putExtra ( SETTING_CHECK_Box,settingList ); startActivityForResult ( intent,0 ); } }
将为结果启动设置活动.这意味着它表现为子活动,并且可以将结果返回到其父活动.
设置列表通过intent传递给设置活动.
protected void onActivityResult ( int requestCode,int resultCode,Intent data ) { if ( resultCode != RESULT_OK || data == null ) return; settingList = (ArrayList < SettingCheckBox >) data.getSerializableExtra ( SETTING_CHECK_Box ); }
您应该让子/设置活动返回(新的/修改的)设置列表,如上所示,设置新列表.
>创建以下名为sub_menu的布局xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout>
这是将充当子菜单的活动布局.它实际上是一个列表活动,可以根据需要保存任意数量的选项(您只需将它们添加到上面活动中声明的数组列表中).
>创建以下名为sub_menu_item的布局xml文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" > <TextView android:id="@+id/option_title" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:textAppearance="@android:style/TextAppearance.Medium" /> <CheckBox android:id="@+id/option_checkBox" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
这是列表中每一行的布局,有一个文本视图和复选框(就像您已经使用的子菜单一样).
>创建一个名为MyActivity_Settings的新类,该类应包含以下内容:
public class MyActivity_Settings extends ListActivity { private ArrayList < SettingCheckBox > settingList; @Override public void onCreate ( Bundle savedInstanceState ) { super.onCreate(savedInstanceState); setContentView ( R.layout.sub_menu ); setTitle ( "Add/Remove" ); settingList = getIntent ().getSerializableExtra ( MainActivity.SETTING_CHECK_Box ); if ( savedInstanceState != null ) { settingList = (ArrayList < SettingCheckBox >) savedInstanceState.getSerializable ( MainActivity.SETTING_CHECK_Box ); } setListAdapter ( new MyActivity_Settings_Adapter ( this,R.layout.item_layout,settingList ) ); } protected void onSaveInstanceState ( Bundle outState ) { super.onSaveInstanceState ( outState ); outState.putSerializable ( MainActivity.SETTING_CHECK_Box,settingList ); } @Override public void finish () { setResult ( RESULT_OK,new Intent ().putExtra ( MainActivity.SETTING_CHECK_Box,settingList ) ); super.finish (); } } class MyActivity_Settings_Adapter extends ArrayAdapter < SettingCheckBox > { private final LayoutInflater layoutInflater; private final int itemResourceId; // Holder pattern (used instead of findViewById for better performance) static class ViewHolder { public TextView title; public CheckBox checkBox; } // Constructor public MyActivity_Settings_Adapter ( ListActivity context,int itemResourceId,List < SettingCheckBox > options ) { super ( context,itemResourceId,options ); layoutInflater = context.getLayoutInflater (); this.itemResourceId = itemResourceId; } // Method called by the list view every time to display a row @Override public View getView ( int position,View convertView,ViewGroup parent ) { // Declare and initialize the row view View rowView = convertView; // Declare the row view holder ViewHolder viewHolder; // Check if an inflated view is provided if ( rowView == null ) { // A new view must be inflated rowView = layoutInflater.inflate ( itemResourceId,null ); // Declare and initialize a view holder viewHolder = new ViewHolder (); // Retrieve a reference to the row title viewHolder.title = (TextView) rowView.findViewById ( R.id.option_title ); // Retrieve a reference to the row check Box viewHolder.checkBox = (CheckBox) rowView.findViewById ( R.id.option_checkBox ); // Store the view holder as tag rowView.setTag ( viewHolder ); } // End if else // An inflated view is already provided,retrieve the stored view holder viewHolder = (ViewHolder) rowView.getTag (); // Set the option title viewHolder.title.setText ( getItem ( position ).getDescription () ); // Set the option check Box state viewHolder.checkBox.setChecked ( getItem ( position ).getChecked () ); // Assign a click listener to the checkBox viewHolder.checkBox.setOnClickListener( new OnClickListener() { public void onClick ( View checkBox ) { // Retrieve the stored view holder ViewHolder viewHolder = (ViewHolder) ((View) checkBox.getParent()).getTag(); // Update the option state getItem ( position ).setChecked ( ! getItem ( position ).getChecked () ); // Display the new option state viewHolder.checkBox.setChecked ( getItem ( position ).getChecked () ); } }); // Return the row view for display return rowView; } // End of getView }
此类表示将充当子菜单的活动.正如我之前所说,它是一个List活动(因此应该扩展ListActivity).为了显示列表中的各种选项,您需要一个适配器(数组适配器足以满足这种情况),这是MyActivity_Settings_Adapter类(扩展ArrayAdapter)的角色.
如果列表活动完成(用户单击后退按钮,或活动外部显示为对话框的任何位置),则它(活动)将新选项列表返回给父活动,并使用新的选中值.
适配器将构建要显示的列表的每一行.
此外,适配器将为每个复选框分配一个单击侦听器,以便在选中(或取消选中)时,将相应地修改该选项.
如果单击子菜单外的任何位置(或只需按后退按钮),子菜单将消失,用户选择将保留在主活动的布尔数组中.
如果你不熟悉ListActivity和ArrayAdapter,这个tutorial会有很多帮助!
>不要忘记在你的android manifest xml文件中添加它(在应用程序标记中):
<activity android:name=".MyActivity_Settings" android:theme="@android:style/Theme.Dialog" />
应用的主题(@android:style / Theme.Dialog)将使活动看起来像子菜单.
希望能帮助到你 !我尝试过它,效果很好!尝试一下,让我知道会发生什么.