经常需要在应用中使用单选和多选列表,单选和多选列表有些是固定选择项的,有些是不固定选择项数目的,需要根据数据个数类型等动态生成单选或者多选列表。
一. 先来说说单选列表:
- 单选列表的首选方案是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”,就可以实现多选。