ListView与RadioButton组合——自定义单选列表

 
标签: radiobuttonlistviewandroidlayout
 分类:

Android自带的RadioButton单选框只支持添加文字,我们自己写Adapter实现自定义的RadioButton

首先item的XML源码

search_user_item.xml (现在只是文字+单选按钮+自定义背景,可以根据需要随意扩展)

 

[html] view plain copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/search_user_list_item"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="30dp"  
  6.     android:layout_marginBottom="10dp"  
  7.     android:layout_marginTop="10dp"  
  8.     android:background="@drawable/more_item_press"  
  9.     android:gravity="center_vertical"  
  10.     android:orientation="horizontal" >  
  11.   
  12.     <TextView  
  13.         android:id="@+id/search_user_name"  
  14.         android:layout_width="200dp"  
  15.         android:layout_height="wrap_content"  
  16.         android:layout_marginLeft="30dp"  
  17.         android:gravity="left"  
  18.         android:textColor="@android:color/black"  
  19.         android:textSize="16sp" />  
  20.   
  21.     <RadioButton  
  22.         android:id="@+id/radio_btn"  
  23.         android:layout_width="wrap_content"  
  24.         android:layout_height="wrap_content"  
  25.         android:layout_marginLeft="10dp" />  
  26.   
  27. </LinearLayout>  

 

Listview就是用系统自带的

 

[html] view plain copy
 
  1. <ListView  
  2.     android:id="@+id/search_user_list"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="200dp"  
  5.     android:layout_marginLeft="5dp"  
  6.     android:layout_marginRight="5dp"  
  7.     android:paddingBottom="5dp"  
  8.     android:cacheColorHint="@android:color/transparent"  
  9.     android:divider="@null"  
  10.     android:listSelector="@android:color/transparent"  
  11.     android:visibility="gone" >  
  12. </ListView>  

再来是Adapter代码

 

SearchUserAdapter.java (具体改动写在代码注释里面)

 

[java] view plain copy
 
  1. package ouc.sei.suxin.android.ui.adapter;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5.   
  6. import ouc.sei.suxin.R;  
  7. import android.content.Context;  
  8. import android.view.LayoutInflater;  
  9. import android.view.View;  
  10. import android.view.ViewGroup;  
  11. import android.widget.BaseAdapter;  
  12. import android.widget.LinearLayout;  
  13. import android.widget.RadioButton;  
  14. import android.widget.TextView;  
  15.   
  16. public class SearchUserAdapter extends BaseAdapter {  
  17.       
  18.     private Context context;  
  19.     private List<String> userList;  
  20.     HashMap<String,Boolean> states=new HashMap<String,Boolean>();//用于记录每个RadioButton的状态,并保证只可选一个  
[java] view plain copy
 
  1. public SearchUserAdapter(Context context, List<String> userList)  
  2. {  
  3.     this.context = context;  
  4.     this.userList= userList;  
  5. }  
  6.   
  7. @Override  
  8. public int getCount() {  
  9.     return userList.size();  
  10. }  
  11.   
  12. @Override  
  13. public Object getItem(int position) {  
  14.     return userList.get(position);  
  15. }  
  16.   
  17. @Override  
  18. public long getItemId(int position) {  
  19.     return position;  
  20. }  
  21.   
  22. @Override  
  23. public View getView(final int position, View convertView, ViewGroup parent) {  
  24.     ViewHolder holder;  
  25.     if (convertView == null) {  
  26.         convertView = LayoutInflater.from(context).inflate(R.layout.search_user_item, null);  
  27.         holder = new ViewHolder();  
  28.         holder.background = (LinearLayout) convertView.findViewById(R.id.search_user_list_item);  
  29.         holder.userName = (TextView) convertView.findViewById(R.id.search_user_name);  
  30.         convertView.setTag(holder);  
  31.     }else{  
  32.         holder=(ViewHolder) convertView.getTag();  
  33.     }  
  34.        final RadioButton radio=(RadioButton) convertView.findViewById(R.id.radio_btn);  
  35.     holder.rdBtn = radio;  
  36.       
  37.     holder.userName.setText(userList.get(position));  
  38.     //根据Item位置分配不同背景          
  39.     if(userList.size() > 0)  
  40.     {  
  41.         if(userList.size() == 1)  
  42.         {  
  43.             holder.background.setBackgroundResource(R.drawable.more_item_press);  
  44.         }  
  45.         else{  
  46.             if(position == 0){  
  47.                 holder.background.setBackgroundResource(R.drawable.more_itemtop_press);  
  48.             }  
  49.             else if(position == userList.size()-1){  
  50.                 holder.background.setBackgroundResource(R.drawable.more_itembottom_press);  
  51.             }  
  52.             else{  
  53.                 holder.background.setBackgroundResource(R.drawable.more_itemmiddle_press);  
  54.             }  
  55.         }  
  56.     }  
  57. //当RadioButton被选中时,将其状态记录进States中,并更新其他RadioButton的状态使它们不被选中      
  58.        holder.rdBtn.setOnClickListener(new View.OnClickListener() {  
  59.              
  60.            public void onClick(View v) {  
  61.                
  62.                //重置,确保最多只有一项被选中  
  63.                for(String key:states.keySet()){  
  64.                    states.put(key, false);  
  65.                      
  66.                }  
  67.                states.put(String.valueOf(position), radio.isChecked());  
  68.                SearchUserAdapter.this.notifyDataSetChanged();  
  69.            }  
  70.        });  
  71.       
  72.        boolean res=false;  
  73.        if(states.get(String.valueOf(position)) == null || states.get(String.valueOf(position))== false){  
  74.            res=false;  
  75.            states.put(String.valueOf(position), false);  
  76.        }  
  77.        else  
  78.            res = true;  
  79.          
  80.        holder.rdBtn.setChecked(res);  
  81.   
  82.     return convertView;  
  83. }  
  84.   
  85. static class ViewHolder {  
  86.    LinearLayout background;  
  87.           TextView userName;  
  88.           RadioButton rdBtn;  
  89. }  

List适配代码(与一般无异):

 

 

[java] view plain copy
 
  1. adapter = new SearchUserAdapter(this, searchUserList);  
  2. searchUserLV.setAdapter(adapter);  
  3. searchUserLV.setVisibility(View.VISIBLE);  
  4. setListViewHeightBasedOnChildren(searchUserLV);  

这里还根据内容动态设置了一下,具体函数如下:

 

 

[java] view plain copy
 
  1. public void setListViewHeightBasedOnChildren(ListView listView) {  
  2.   
  3.     Adapter listAdapter = listView.getAdapter();  
  4.   
  5.     if (listAdapter == null) {  
  6.         return;  
  7.     }  
  8.   
  9.     int totalHeight = 0;  
  10.     int viewCount = listAdapter.getCount();  
  11.     for (int i = 0; i < viewCount; i++) {  
  12.         View listItem = listAdapter.getView(i, null, listView);  
  13.         listItem.measure(0, 0);  
  14.         totalHeight += listItem.getMeasuredHeight();  
  15.     }  
  16.   
  17.     ViewGroup.LayoutParams params = listView.getLayoutParams();  
  18.   
  19.     params.height = totalHeight  
  20.             + (listView.getDividerHeight() * (listAdapter.getCount()-1)) + 10;//加10是为了适配自定义背景  
  21.   
  22.     listView.setLayoutParams(params);  
  23. }  

当需要获取ListView中RadioButton的选择状态时,可以直接看Adapter中的states,具体如下:

 

 

[java] view plain copy
 
  1. // 根据RadioButton的选择情况确定用户名  
  2. for (int i = 0, j = searchUserLV.getCount(); i < j; i++) {  
  3.     View child = searchUserLV.getChildAt(i);  
  4.     RadioButton rdoBtn = (RadioButton) child  
  5.             .findViewById(R.id.radio_btn);  
  6.     if (rdoBtn.isChecked())  
  7.         searchUser = searchUserList.get(i);  
  8. }  

这里的searchUserList是调用后台服务获取的用户名列表,通过states获取选中用户名进行后续操作

 

 

效果图:

 

 

 
0
0
 

我的同类文章

猜你在找
查看评论
6楼 xuan237812939 2015-12-29 18:58发表 [回复]
楼主思路很好
5楼 superyuanzhe 2015-12-26 19:29发表 [回复]
4楼 chuanglio 2015-10-27 14:34发表 [回复]
当获取ListView中RadioButton的选择状态时循环到看不见的行数
RadioButton rdoBtn = (RadioButton) child .findViewById(R.id.radio_btn); 
会出现空指针
3楼 樱花_殇 2015-05-25 17:14发表 [回复]
终于解决了,找了这个多资料,楼主这个是我找的里面最简单改动最少的一个,不错,谢谢楼主...
2楼 淘_tao 2014-06-10 13:55发表 [回复]
可以看看。。。。。。。
1楼 duduzaidudumei 2014-03-26 15:35发表 [回复]
关于状态的判断,不需要保存全部位置的状态,可以只保存一个值,被选中的position,当重新刷新view的时候判断map是否包含当前的position即可。这样数据比较多的时候,节省遍历的消耗。
Re: KANGOD_KING 2015-09-16 11:47发表 [回复]
回复duduzaidudumei:确实。
不过也用不到map了,只用一个int就行。
holder.radioButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mCheckedPosition = position;
notifyDataSetChanged();
}
});
重新刷新view的时候holder.radioButton.setChecked(position == mCheckedPosition);
Re: hety163 2014-04-23 10:22发表 [回复]
回复duduzaidudumei:一楼正解,楼主的方法虽然也能实现,但是比较消耗性能。
 
http://blog.csdn.net/checkin001/article/details/11519131
posted @ 2016-01-21 14:14  a318013800  阅读(2158)  评论(0编辑  收藏  举报