单选列表和复选列表

经常需要在应用中使用单选和多选列表,单选和多选列表有些是固定选择项的,有些是不固定选择项数目的,需要根据数据个数类型等动态生成单选或者多选列表。


一. 先来说说单选列表:

  • 单选列表的首选方案是RadioGroup
    (1) 下面是固定选项个数的RadioGroup实现的单选列表,固定列表可以直接在xml中如下定义
<!--<RadioGroup
       android:id="@+id/radioGroup1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:orientation="vertical"
       >
      <RadioButton
          android:id="@+id/radioBtn1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="radioBtn1"
          />
      <RadioButton
          android:id="@+id/radioBtn2"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="radioBtn2"
          />
      <RadioButton
          android:id="@+id/radioBtn3"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="radioBtn3"
          />
   </RadioGroup>-->

对于固定RadioGroup单选列表可以使用下面的方式进行监听处理。

 final RadioGroup  raGroup1 = (RadioGroup) findViewById(R.id.radioGroup1);
 raGroup1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {  
            @Override 
            public void onCheckedChanged(RadioGroup group, int checkedId) {  
                // TODO Auto-generated method stub  
                if(checkedId==R.id.radioBtn1){                    
                    Toast.makeText(MainActivity.this, "AAAA", Toast.LENGTH_LONG).show();  
                }  
                else if(checkedId==R.id.radioBtn2){  
                    Toast.makeText(MainActivity.this, "BBBB", Toast.LENGTH_LONG).show();  
                }  
                else{  
                    Toast.makeText(MainActivity.this, "CCCC", Toast.LENGTH_LONG).show();  
                }  
            }  
        });  

也可以通过RadioGroup来获取到选中的RadioButton,再根据选中的RadioButton进行处理。

        RadioGroup  raGroup1 = (RadioGroup) findViewById(R.id.radioGroup1);
        raGroup1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //checkedId是选中的RadioButton在xml中定义的时候的控件的id值。
                //checkedId 和 group.getCheckedRadioButtonId()是一样的。
                RadioButton rb = (RadioButton) findViewById(group.getCheckedRadioButtonId());
                Toast.makeText(MainActivity.this, rb.getText().toString(), Toast.LENGTH_LONG).show();
            }
        });

(2) RadioGroup实现动态数目的单选列表
动态的RadioGroup只是把固定写在布局中的RadioButton通过代码动态生成添加到RadioGroup视图中。先在xml文件中定义一个RadioGroup

<RadioGroup
        android:id="@+id/num_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"/>

再定义一个xml文件作为RadioGroup的子项 visitor_num_item_radiobutton.xml

<RadioButton
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="@dimen/x100"
  android:background="@color/white"
  android:textSize="@dimen/x32"
  android:textColor="@drawable/radiobtn_txt_green_selector"
  android:gravity="left|center_vertical"
  android:button="@null"
  android:drawableRight="@drawable/small_blue_checkbox_selector"
  android:paddingRight="@dimen/x30"
  android:paddingLeft="@dimen/x30">
</RadioButton>

代码中动态生成RadioButton添加到RadioGroup中。

/**
     * 填充数据
     */
    mRadioGroup = (RadioGroup) mMenuView.findViewById(R.id.num_list);
    private void initData(ArrayList<String> mArrayList) {
        if(null != mArrayList && mArrayList.size() > 0){
            for (int i = 0; i < mArrayList.size(); i++) {
                RadioButton child = (RadioButton) LayoutInflater.from(mContext).inflate(R.layout.visitor_num_item_radiobutton, null);
                child.setLayoutParams(new LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT,(int)mContext.getResources().getDimensionPixelSize(R.dimen.x88)));
                child.setText(mArrayList.get(i));
                child.setTag(mArrayList.get(i));
                mRadioGroup.addView(child);
            }
        }else{
            mRadioGroup.setVisibility(View.GONE);
        }
    }

同样要对RadioGroup实现监听

 mRadioGroup .setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //添加监听
            }
        });
  • ListView本身实现的动态单选列表
    ListView有一个属性是 android:choiceMode 这个属性设置可以让ListView实现单选和多选的效果。
    关于这个参数的具体设置 可以参考 anddlecn 的 一篇博文 https://blog.csdn.net/anddlecn/article/details/51579709
    (1) 首先实现单选列表
    先定义一个设置了android:choiceMode=”singleChoice” 的ListView
 <!--<ListView
       android:id="@+id/event_lv_name"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:choiceMode="singleChoice"
       android:cacheColorHint="@null"
       android:dividerHeight="1dp"
       android:scrollbars="@null" >
   </ListView>-->

ListView的适配器代码如下

    public class MyAdapter extends BaseAdapter {
        private LayoutInflater mInflater = null;

        private MyAdapter(Context context) {
            this.mInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        //Get a View that displays the data at the specified position in the data set.
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                //Item View 
                convertView = mInflater.inflate(R.layout.checkable_item, null);
                holder.info = (CheckBox) convertView.findViewById(R.id.item_checkbox);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.info.setText(list.get(position));
            return convertView;
        }

        @Override
        public boolean hasStableIds() {
            return true ;
        }
    }

    //ViewHolder静态类
    static class ViewHolder {
        public CheckBox info;
    }

上面的代码就是一个普通的适配器,只是引用的Item view的项需要注意一下。一般的Item view 的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="match_parent"
    android:padding="10dp" >

    <CheckBox
        android:id="@+id/item_checkbox"
        android:focusable="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:button="@null"
        android:drawableRight="@drawable/small_blue_checkbox_selector"
        android:clickable="false"
        android:text="@string/app_name"
        />

</LinearLayout>

如上定义的xml文件的item view不会响应ListView的 check效果。因为ListView 的子View 需要实现了Checkable 接口才能选中。布局中的checkbox需要添加下面两个属性,并设置为false,因为listview设置了android:choiceMode属性,提供了可选中的效果。
android:clickable=”false”
android:focusable=”false”
这个是checkBox选中效果的设置的右边的图标变化
android:drawableRight=”@drawable/small_blue_checkbox_selector”

所以有两种解决办法:
第一种是直接使用CheckBox作为根布局 ,去掉外层的LinearLayout

<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_checkbox"
    android:focusable="false"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:button="@null"
    android:drawableRight="@drawable/small_blue_checkbox_selector"
    android:clickable="false"
    android:text="@string/app_name"
    />

第二种是在外层加一层自定义的继承了checkable的布局:

<?xml version="1.0" encoding="utf-8"?>
<com.example.administrator.mytestdemo.CheckableFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp" >

    <CheckBox
        android:id="@+id/item_checkbox"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:button="@null"
        android:drawableRight="@drawable/small_blue_checkbox_selector"
        android:clickable="false" 
        android:focusable="false"
        android:text="@string/app_name"
        />

</com.example.administrator.mytestdemo.CheckableFrameLayout>

CheckableFrameLayout 的定义代码如下

public class CheckableFrameLayout extends FrameLayout implements Checkable{

    public boolean mChecked = false;
    public CheckableFrameLayout(Context context, AttributeSet attrs,
                                int defStyle) {
        super(context, attrs, defStyle);
    }

    public CheckableFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CheckableFrameLayout(Context context) {
        super(context);
    }

    @Override
    public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState();
            for (int i = 0, len = getChildCount(); i < len; i++) {
                View child = getChildAt(i);
                if(child instanceof Checkable){
                    ((Checkable) child).setChecked(checked);
                }
            }
        }
    }

    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void toggle() {
        setChecked(!mChecked);
    }

}

这样设置的ListView就可以满足单选的效果, 通过ListView 添加 onItemClickListener监听点击效果。

二. 多选列表
(1) CheckBox实现复选按钮,如果是固定个数的选项,还是在xml文件中布局。

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
    <TextView    
        android:layout_width="fill_parent"   
        android:layout_height="wrap_content"   
        android:text="@string/hello" 
        android:textSize="20sp" 
        android:textStyle="bold" 
        android:textColor="#FFFFFF" 
        /> 
    <CheckBox 
        android:id="@+id/checkbox1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="@string/football" 
        android:textSize="16sp" 
        /> 
    <CheckBox 
        android:id="@+id/checkbox2" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="@string/basketball" 
        android:textSize="16sp" 
        /> 
    <CheckBox 
        android:id="@+id/checkbox3" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="@string/volleyball" 
        android:textSize="16sp" 
        />        
</LinearLayout> 

基本上和RadioGroup的使用差不多。

(2)第二种多选列表通过ListView实现
在定义listview的xml文件的时候只要相对单选修改一个属性android:choiceMode。将android:choiceMode=”singleChoice”修改成 android:choiceMode=”multipleChoice”,就可以实现多选。

猜你喜欢

转载自blog.csdn.net/ysq_chris/article/details/80782061