android 自定义ListView 使其带单选框按钮,并解决item点击不响应的问题

自己定义ListView就要自己写个LIstviewAdapter继承BaseAdapter这个类然后通过其中的getView()方法把数据映射到相应控件之中

下面是我实现的带单选框的listView(如果是想带按钮实现更简单,就不需要考虑单选框的按钮特性了)

在做的过程之中出现了点击item无响应的情况,最后发现是子控件radioButton获得了焦点是其父控件即item失去了焦点所以在getView ()之中让RadioButton失去焦点即可

先放个效果图

代码如下

package com.example.mylistview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;

public class MyListViewWithRadio extends Activity implements OnItemClickListener {

	private ListView listView;
	private List> mData;
	
	//record the current checked radio number
	private int checkedIndex = -1;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		mData = getData();
		listView = new ListView(this);		
		MyAdapter myAdapter = new MyAdapter(this);
		listView.setAdapter(myAdapter);
		listView.setOnItemClickListener(this);
		setContentView(listView);
	}
	
	//获取要在list中显示的数据
	private List> getData(){
		List> list = new ArrayList>();
		Map map = new HashMap();
		
		map.put("title", "G1");
		map.put("info", "google 1");
		map.put("img", R.drawable.wear_breast);
		list.add(map);

		map = new HashMap();
		map.put("title", "G2");
		map.put("info", "google 2");
		map.put("img", R.drawable.wear_wasit);
		list.add(map);

		map = new HashMap();
		map.put("title", "G3");
		map.put("info", "google 3");
		map.put("img", R.drawable.wear_wrist);
		list.add(map);
		
		map = new HashMap();
		map.put("title", "G4");
		map.put("info", "google 4");
		map.put("img", R.drawable.wearl_ankle);
		list.add(map);
		
		map = new HashMap();
		map.put("title", "G5");
		map.put("info", "google 5");
		map.put("img", R.drawable.wear_breast);
		list.add(map);

		map = new HashMap();
		map.put("title", "G6");
		map.put("info", "google 6");
		map.put("img", R.drawable.wear_wasit);
		list.add(map);

		map = new HashMap();
		map.put("title", "G7");
		map.put("info", "google 7");
		map.put("img", R.drawable.wear_wrist);
		list.add(map);
		
		map = new HashMap();
		map.put("title", "G8");
		map.put("info", "google 8");
		map.put("img", R.drawable.wearl_ankle);
		list.add(map);
		
		map = new HashMap();
		map.put("title", "G9");
		map.put("info", "google 9");
		map.put("img", R.drawable.wear_breast);
		list.add(map);

		map = new HashMap();
		map.put("title", "G10");
		map.put("info", "google 10");
		map.put("img", R.drawable.wear_wasit);
		list.add(map);

		map = new HashMap();
		map.put("title", "G11");
		map.put("info", "google 11");
		map.put("img", R.drawable.wear_wrist);
		list.add(map);
		
		map = new HashMap();
		map.put("title", "G12");
		map.put("info", "google 12");
		map.put("img", R.drawable.wearl_ankle);
		list.add(map);
		
		return list;
	}
	

	//实现点击整个item时  都会触发单选框的 动作
	@Override
	public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) {
		// arg0:当前的listview。arg1:当前点击的item的句柄,arg2:当前item在listview中的position
		//arg3:当前listview中行数一般和position相等
		System.out.println("取position和id的值:"+arg2+"--"+arg3);
		ListView lv = (ListView)arg0;
              if(checkedIndex != arg2){ 
              {  //定位到现在处于点击状态的radio
            	  System.out.println("checkedIndex != arg2");
                  int childId = checkedIndex - lv.getFirstVisiblePosition();  
                  if(childId >= 0){  //如果checked =true的radio在显示的窗口内,改变其状态为false
                      View item = lv.getChildAt(childId);  
                      if(item != null){  
                          RadioButton rb = (RadioButton)item.findViewById(checkedIndex);  
                          if(rb != null)  
                          rb.setChecked(false);  
                      }  
                  }
                  //将当前点击的radio的checked变为true
                  RadioButton rb1 = (RadioButton)arg1.findViewById(arg2);  
                  if(rb1 != null)  
                  rb1.setChecked(true);
                  checkedIndex = arg2;
              }
              }	
	}
		
	//存放listview中的数据项
	public final class ViewHolder{
		public ImageView img;
		public TextView title;
		public TextView info;
		public RadioButton viewBtn;
	}
	
	//自定义listview adapter
	public class MyAdapter extends BaseAdapter{

		private LayoutInflater mInflater;
		
		
		public MyAdapter(Context context){
			this.mInflater = LayoutInflater.from(context);
		}
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return mData.size();
		}

		@Override
		public Object getItem(int arg0) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int arg0) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			ViewHolder holder = null;
			if (convertView == null) {//convertView 存放item的
				holder=new ViewHolder();  			
				convertView = mInflater.inflate(R.layout.activity_mylistviewwithradio, null);
				holder.img = (ImageView)convertView.findViewById(R.id.img2);
				holder.title = (TextView)convertView.findViewById(R.id.title2);
				holder.info = (TextView)convertView.findViewById(R.id.info2);
				holder.viewBtn = (RadioButton)convertView.findViewById(R.id.listview2_radiobutton);
				convertView.setTag(holder);
				
			}else {
				
				holder = (ViewHolder)convertView.getTag();
			}
			
			
			holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
			holder.title.setText((String)mData.get(position).get("title"));
			holder.info.setText((String)mData.get(position).get("info"));
			
			//让子控件button失去焦点  这样不会覆盖掉item的焦点  否则点击item  不会触发响应即onItemClick失效
			holder.viewBtn.setFocusable(false);//无此句点击item无响应的
			holder.viewBtn.setId(position);  
			holder.viewBtn.setChecked(position == checkedIndex);  
			
			holder.viewBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  
                @Override  
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
                    if(isChecked){  
                        //set pre radio button  
                        if(checkedIndex != -1)  
                        {  
                            int childId = checkedIndex - listView.getFirstVisiblePosition();  
                            if(childId >= 0){  
                                View item = listView.getChildAt(childId);  
                                if(item != null){  
                                    RadioButton rb = (RadioButton)item.findViewById(checkedIndex);  
                                    if(rb != null)  
                                    rb.setChecked(false);  
                                }  
                            }    
                        }  
                        //set cur radio button  
                        checkedIndex = buttonView.getId();  
                    }  
                }  
            });  
			return convertView;
		}
		
	}


}
layout中的XML代码如下:



















你可能感兴趣的:(android)