ListView中自带选择模式,这里是要实现单选,所以设置listview属性为singlechoice,为单选模式,Listview布局如下:

<ListView
    android:id="@+id/lv_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:choiceMode="singleChoice"
    android:dividerHeight="1dp"
    android:divider="#e1e1e1"/>
item的布局如下,就一个TextView加上一个RadioButton

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:padding="20dp"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/tv_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <RadioButton
        android:id="@+id/rb_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:button="@drawable/selector_button"/>

</RelativeLayout>
注意RadioButton这里需要设置这三个属性,clickable、focusable和focusableInTouchMode全部设置为false,否则点击事件会被RadioButton消费,无法实现效果。


selector_button文件

<item android:state_checked="false" android:drawable="@drawable/white_bg"></item>
<item android:state_checked="true" android:drawable="@mipmap/list_success"></item>
这里如果是false的时候,我是自己定义了一个白色背景的矩形来代替的,大家可以用根据自己的需求来替换,下面是shape的代码

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size android:width="22dp" android:height="22dp" />
    <solid android:color="#fff" />
</shape>
这里我一开始是没有设置size的只设置了solid,点击的时候radiobutton一点反应都没有,加上size后就可以了。


自定义一个控件让RadioButton跟随点击ListView的变化而变化,代码如下

public class ChoiceView extends FrameLayout implements Checkable {

    private TextView tv;
    private RadioButton rb;

    public ChoiceView(Context context) {
        super(context);
        View.inflate(context,R.layout.item_listview_main,this);
        tv = (TextView) findViewById(R.id.tv_item);
        rb = (RadioButton) findViewById(R.id.rb_item);
    }

    @Override
    public void setChecked(boolean checked) {
        rb.setChecked(checked);
    }

    @Override
    public boolean isChecked() {
        return rb.isChecked();
    }

    @Override
    public void toggle() {
        rb.toggle();
    }

    public void setTextView(String text){
        tv.setText(text);
    }
}

适配器代码

public class MainAdapter extends BaseAdapter {

    private List<String> mList;
    private Context context;
    private int checkedPosition;

    public MainAdapter(List<String> mList, Context context) {
        this.mList = mList;
        this.context = context;
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ChoiceView view = null;
        if(convertView==null){
            view = new ChoiceView(context);
        }else{
            view = (ChoiceView) convertView;
        }
        view.setTextView(mList.get(position));
        return view;
    }

}

然后只要简单的调用适配器就可以了,通过setOnItemClickListener()可以获取被选中的position

mList = new ArrayList<>();
for (int i=0;i<5;i++){
    mList.add(i+"");
}
listView = (ListView) findViewById(R.id.lv_main);
adapter = new MainAdapter(mList,this);
listView.setAdapter(adapter);

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {//在这里可以得到哪个被选中
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(MainActivity.this,""+position,Toast.LENGTH_SHORT).show();
    }
});


ListView配合RadioButton实现单选列表

相关文章: