如何选择Android上的子菜单中多个复选框? [英] How to select multiple checkboxes in submenu on Android?

查看:532
本文介绍了如何选择Android上的子菜单中多个复选框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个添加/删除选项,点击后,显示了一个可检查的列表中的一个选项菜单。与code,我现在的问题是,你只能一次选择一个项目,菜单消失。我希望能够在列表中选中多个项目的一次,它不消失,直到用户触摸点在屏幕上的其他地方。我怎样才能做到这一点?下面是我有什么总体思路:

 < XML版本=1.0编码=UTF-8&GT?;
<菜单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android>
    <项目机器人:ID =@ + ID /在select_options
          机器人:标题=添加/删除>
        <菜单>
            <组机器人:checkableBehavior =所有>
                <项目机器人:ID =@ + ID / A
                      机器人:检查=真
                      机器人:标题=方案一/>
                <项目机器人:ID =@ + ID / B
                      机器人:检查=真
                      机器人:标题=方案二/>
            < /组>
        < /菜单>
    < /项目>
< /菜单>
 

  @覆盖
公共布尔onCreateOptionsMenu(功能菜单){
    MenuInflater充气= getMenuInflater();
    inflater.inflate(R.menu.selection_menu,菜单);
    返回true;
}

@覆盖
公共布尔onOptionsItemSelected(菜单项项){
    开关(item.getItemId()){
    案例R.id.A:
        item.setChecked(item.isChecked()!);
        返回true;
    案例R.id.B:
        item.setChecked(item.isChecked()!);
        返回true;
   默认:
        返回super.onOptionsItemSelected(项目);
   }
}
 

解决方案

您好TheBeatlemaniac!

我真的不知道,如果你正在寻找什么是可行与否(编辑:在路上要实现它,作为一个子菜单),但我会做这种方式:

创建,看起来像要显示的子菜单的活动。

这似乎有点复杂,但它是直线前进,并以这种方式,它不会,如果你选择/取消的项目消失,可以实现更多的功能。

下面是如何,我会亲自做了:


  • 创建一个类来重新present子菜单项。它应该包含一个字符串(描述),和一个布尔值(存储,如果它被选中与否)。

公共类SettingCheckBox实现Serializable {     私有静态最后长的serialVersionUID = 1L;     私有静态最后弦乐DEFAULT_DESCRIPTION =N / A;     私人最终字符串描述;     私人布尔检查;     公共字符串getDescription(){         返回描述== NULL? DEFAULT_DESCRIPTION:描述;     }     公共无效setChecked(最终布尔检查){         this.checked =检查;     }     公共布尔getChecked(){         返回检查;     }     公共SettingCheckBox(最后的字符串描述){         this.description =描述;     } }

正如你所看到的,这个类实现Serializable接口,这样的类的对象可以从一个活动传递到另一个使用意图/包。

  • 在下面添加到您的当前活动(我假定它被称为 MainActivity ,所以当你尝试一下,将 MainActivity 按你的活动名称)。

公共静态最后弦乐SETTING_CHECK_BOX =SETTING_CHECK_BOX; 私人的ArrayList< SettingCheckBox> settingList; @覆盖 公共无效的onCreate(包savedInstanceState){     // ...     settingList =新的ArrayList< SettingCheckBox> ();     settingList.add(新SettingCheckBox(选项A));     settingList.add(新SettingCheckBox(方案B));     // ...添加更多的商品     //恢复任何previously保存列表     如果(savedInstanceState!= NULL){         settingList =(ArrayList的< SettingCheckBox>)savedInstanceState.getSerializable(SETTING_CHECK_BOX);     }     // ... } 保护无效的onSaveInstanceState(包outState){     super.onSaveInstanceState(outState);     outState.putSerializable(SETTING_CHECK_BOX,settingList); }

列表(ArrayList中)用于承载与复选框所有设置的子菜单项。 正如你所看到的,每个 SettingCheckBox 对象有一个描述和状态(选中或未选中)。默认情况下,一旦创建,对象状态的选中的。 你应该初始化的onCreate 方法中的列表中。

静态和最终的变量 SETTING_CHECK_BOX 作为键保存/恢复前该列表的内容/活动娱乐活动(如屏幕旋转)后,也从一个传递设置列表活动到另一个。 (解释以后)

  • 删除您的子菜单,使菜单的xml文件看起来是这样的:

< XML版本=1.0编码=UTF-8&GT?; <菜单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android>     <项目机器人:ID =@ + ID /在select_options         机器人:标题=添加/删除>     < /项目> < /菜单>

没有必要在子菜单了,因为你会被实施,其作用类似于之一的活动。 现在,链接的菜单项的活动,将显示设置,你应该使用 onOptionsItemSelected 方式您当前的活动里面是这样的:

@覆盖 公共布尔onOptionsItemSelected(菜单项菜单项){     如果(menu​​Item.getItemId()== R.id.select_options){         意向意图=新的意图(这一点,MyActivity_Settings.class);         intent.putExtra(SETTING_CHECK_BOX,settingList);         startActivityForResult(意向,0);     } }

的设置活动被启动的结果。这意味着像它表现为一个子活动,和的可以的返回结果到它的父活动。

的设置列表经由意图传递给设置活动

如果在子活动结束并返回数据到母体活性,下面的方法被称为:

保护无效onActivityResult(INT申请code,INT结果code,意图数据){     如果(结果code!= RESULT_OK ||数据== NULL)         返回;     settingList =(ArrayList的< SettingCheckBox>)data.getSerializableExtra(SETTING_CHECK_BOX); }

您应该让孩子/设置活动返回(新/修改)的设置列表,如上文所示,新的列表设置。

  • 创建以下布局的XML文件名为sub_menu:

 < LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直>

    <的ListView
        机器人:ID =@机器人:ID /列表
        机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT>
    < / ListView控件>

< / LinearLayout中>
 

这是,将作为您的子菜单活动的布局。它实际上是一个列表的活动,只要你想(你只需要添加它们上方的活动声明的数组列表中的),可以容纳尽可能多的选择。

  • 创建以下布局的XML文件名为sub_menu_item:

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:方向=横向
    机器人:重力=center_vertical>

    <的TextView
        机器人:ID =@ + ID / option_title
        机器人:layout_width =0dip
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_weight =1
        机器人:textAppearance =@安卓风格/ TextAppearance.Medium/>

    <复选框
        机器人:ID =@ + ID / option_checkbox
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT/>

< / LinearLayout中>
 

这是列表中的每一行的布局,有一个文本视图和复选框(就像你已经在使用的子菜单)。

  • 创建一个新的名为类MyActivity_Settings应包含以下内容:

公共类MyActivity_Settings扩展ListActivity {     私人的ArrayList< SettingCheckBox> settingList;     @覆盖     公共无效的onCreate(包savedInstanceState){         super.onCreate(savedInstanceState);         的setContentView(R.layout.sub_menu);         的setTitle(添加/删除);         settingList = getIntent().getSerializableExtra(MainActivity.SETTING_CHECK_BOX);         如果(savedInstanceState!= NULL){             settingList =(ArrayList的< SettingCheckBox>)savedInstanceState.getSerializable(MainActivity.SETTING_CHECK_BOX);         }         setListAdapter(新MyActivity_Settings_Adapter(这一点,R.layout.item_layout,settingList));     }     保护无效的onSaveInstanceState(包outState){         super.onSaveInstanceState(outState);         outState.putSerializable(MainActivity.SETTING_CHECK_BOX,settingList);     }     @覆盖     公共无效结束(){         的setResult(RESULT_OK,新的意向().putExtra(MainActivity.SETTING_CHECK_BOX,settingList));         super.finish();     } } 类MyActivity_Settings_Adapter扩展ArrayAdapter< SettingCheckBox> {     私人最终LayoutInflater layoutInflater;     私人最终诠释itemResourceId;     //持有人模式(用来代替findViewById获得更好的性能)     静态类ViewHolder {         公共TextView的称号;         公开复选框复选框;     }     //构造函数     公共MyActivity_Settings_Adapter(ListActivity方面,诚信itemResourceId,名单,其中,SettingCheckBox>选项){         超(背景下,itemResourceId,期权);         layoutInflater = context.getLayoutInflater();         this.itemResourceId = itemResourceId;     }     //方法每次显示一行时调用列表视图     @覆盖     公共查看getView(INT位置,查看convertView,ViewGroup中父){         //声明并初始化行视图         查看rowView = convertView;         //声明该行认为持有人         ViewHolder viewHolder;         //检查是否提供了一种充气视图         如果(rowView == NULL){             //一个新视图必须充气             rowView = layoutInflater.inflate(itemResourceId,NULL);             //声明并初始化一个视​​图架             viewHolder =新ViewHolder();             //检索引用的行标题             viewHolder.title =(TextView中)rowView.findViewById(R.id.option_title);             //检索引用的行复选框             viewHolder.checkBox =(复选框)rowView.findViewById(R.id.option_checkbox);             //存储视图持有人的标签             rowView.setTag(viewHolder);         } // 万一         其他         //一个膨胀的看法已经提供,获取存储视图架         viewHolder =(ViewHolder)rowView.getTag();         //设置选项标题         viewHolder.title.setText(的getItem(位置).getDescription());         //设置选项复选框的状态         viewHolder.checkBox.setChecked(的getItem(位置).getChecked());         //指定一个点击监听器的复选框         viewHolder.checkBox.setOnClickListener(新OnClickListener(){             公共无效的onClick(查看复选框){                 //检索存储的观点持有人                 ViewHolder viewHolder =(ViewHolder)((视图)checkBox.getParent())getTag()。                 //更新选项状态                 的getItem(位置).setChecked(的getItem(位置).getChecked()!);                 //显示新的选择状态                 viewHolder.checkBox.setChecked(的getItem(位置).getChecked());             }         });         //返回的行视图显示         返回rowView;     } // getView结束 }

本类重presents,将作为您的子菜单的活动。正如我previously说,这是一个列表活动(因此应该扩展ListActivity)。为了显示列表里面的各种选项,你需要一个适配器(阵列适配器是足够的这种情况下),这就是MyActivity_Settings_Adapter类的角色(即扩展ArrayAdapter)。

如果列表活动完成(用户点击返回按钮,或任何其上显示作为对话的活动外),它(活动)返回到父活动的选择与新的检查值的新列表

该适配器将建立各行的列表中显示。 此外,该适配器将分配一个点击监听每个复选框,这样,如果选中(或取消选中)的选项将被相应的修改。

如果你点击任何地方的子菜单之外(或者干脆$的背面按钮p $ PSS),子菜单会消失,而用户选择是preserved布尔数组中的主要活动在

如果您不熟悉ListActivity和ArrayAdapter,这教程将有助于很多!

  • 请不要忘记添加这在你的Andr​​oid清单xml文件(在应用程序标签):

<活动机器人:MyActivity_SettingsNAME =         机器人:主题=@安卓风格/ Theme.Dialog/>

应用的主题。(@android:款式/ Theme.Dialog)将会使活动看起来像一个子菜单

希望它能帮助! 我尝试过了,它完美的作品!试试吧,让我知道会发生什么。

I have an options menu with an "Add/Remove" option that, when clicked, shows a checkable list. The problem with the code that I currently have is that you can only select one item at a time, and the menu disappears. I want to be able to check multiple items in the list at once, and for it not to disappear until the user touches a spot elsewhere on the screen. How can I do this? Here's the general idea of what I have:

<?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>

and

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

解决方案

Hello TheBeatlemaniac !

I honestly don't know if what you are seeking for is doable or not ( EDIT : in the way you are implementing it, as a sub menu ), but I would have done it this way:

Create an activity that looks like the sub menu you want to display.

It might seem a little bit more complicated but it is straight forward and in this manner, it will not disappear if you select / deselect an item, and you can implement much more functionality.

Here's how I would have personally done it:


  • Create a class to represent a sub menu item. It should contain a string (description), and a boolean (to store if it is checked or not).

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

}

As you can see, the class implements Serializable so that objects of that class can be passed from an activity to another using intents/bundles.

  • Add the following to your current activity (I assumed it is called MainActivity, so while you try it, replace MainActivity by your activity name).

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

The list (ArrayList) is used to host all your setting sub menu items with the check boxes. As you can see, each SettingCheckBox object has a description and a state (checked or unchecked). By default, once create, the object state is unchecked. You should initialize the list inside the onCreate method.

The static and final variable SETTING_CHECK_BOX is used as key to save/restore the content of that list before/after activity recreations (like a screen rotation), and also to pass the settings list from an activity to another. (explained later on)

  • Remove your sub menu, so that the menu xml file looks like this:

<?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>

No need for the sub menu anymore since you will be implementing an activity that acts like one. Now, to link the menu item to the activity that will display the settings, you should use the onOptionsItemSelected method inside your current activity like this :

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

The settings activity is started for a result. It means like it behaves as a child activity, and can return a result to its parent activity.

The settings list is passed to the settings activity via the intent.

If the child activity ends and returns data to the parent activity, the following method is called :

protected void onActivityResult ( int requestCode , int resultCode , Intent data ) {
    if ( resultCode != RESULT_OK || data == null )
        return;
    settingList = (ArrayList < SettingCheckBox >) data.getSerializableExtra ( SETTING_CHECK_BOX );
}

You should make the child / settings activity return the (new/modified) list of settings, and as demonstrated above, the new list is set.

  • Create the following layout xml file called sub_menu:

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

This is the layout of the activity that will act as your sub menu. It is actually a list activity, and can hold as many options as you want (you just add them in the array list declared in your activity above).

  • Create the following layout xml file called sub_menu_item:

<?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>

This is the layout of each row in the list, there is a text view and check box ( just like the sub menu you were already using).

  • Create a new class entitled MyActivity_Settings that should contain the following:

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

}

This class represents the activity that will act as your sub menu. As I previously said, it is a List Activity (and hence should extend ListActivity). In order to display the various options inside the list, you need an adapter (array adapter is sufficient for this case), that's the role of the MyActivity_Settings_Adapter class (that extends ArrayAdapter ).

If the list activity finishes (the user clicks on the back button, or anywhere outside the activity which is displayed as a dialog), it (the activity) returns to the parent activity the new list of options with the new checked values.

The adapter will build each row for the list to display. In addition, the adapter will assign a click listener for every check box, so that if checked (or unchecked) the option will be modified accordingly.

And if you click anywhere outside the sub menu (or simply press on the back button), the sub menu will disappear, and the user selections are preserved in the boolean array in your main activity.

If you are not familiar with ListActivity and ArrayAdapter, this tutorial would help a lot !

  • Do not forget to add this in your android manifest xml file (in the application tag):

    <activity android:name=".MyActivity_Settings"
        android:theme="@android:style/Theme.Dialog" />

The theme applied (@android:style/Theme.Dialog) will make the activity look like a sub menu.

Hope it helps ! I tried it and it works perfectly ! Try it and let me know what happens.

这篇关于如何选择Android上的子菜单中多个复选框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆