问题描述:
我在进行android开发的过程中经常使用listview来显示数据,但是listview中的数据不是传统意义上的文字或图片,往往会有其他ui组件,而且还要根据需要为它们添加事件监听器,这个时候就需要自定义listview的适配器然后重载里面的getview()方法了。
Getview()方法是baseadapter里面一个重要的方法,它是在android显示listview里面的内容的时候回调的一个方法。下面就讲讲这个方法的工作机制(个人观点,如有不对,望指出)现在假设我们有10项内容要显示,但是一屏只能显示5项,那么android会首先创建6项对应的item的view的实例并缓存起来,当滑动屏幕,第一项还未移除屏幕,然后第6项已经进入了屏幕的时候,就会把多余的那个view实例用来显示第6项的内容,只有在第7项已经进入屏幕,但是第1项还未移除屏幕的时候才会新建一个view来显示同时缓存起来,此后就将移除屏幕的view用来显示新进入屏幕的item。其实有点类似于线程池的机制。这样的话我们的代码往往会这样写:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view=null;
ViewHolder holder=null;
if(convertView==null){
convertView=LayoutInflater.from(context).inflate(R.layout.item, null);
holder=new ViewHolder();
holder.text=(TextView) convertView.findViewById(R.id.text);
holder.check=(CheckBox)convertView.findViewById(R.id.check);
convertView.setTag(holder);
}
else{
view =convertView;
holder=(ViewHolder)view.getTag();
}
holder.text.setText(list[position]);
return convertView;
}
其实这样可以大大的提高listview的效率,特别是当item项很多的时候,不用为每一个item新建一个view来显示,而只是固定数量的一些来循环的显示。
继续进行我们的研究,我们的目的是要为自己的 ui组件添加事件响应,但是这样又出先了一个问题,因为我们对ui组件的重用,这样一来当屏幕滑动的时候ui组件就会相互重叠,比如的view里有一个checkbox当你选中以后,在滑动屏幕,可能在下面的莫一项上重用此组件的checkbox已被选上,这样就形成了干扰,下面的代码解决了这个问题,以checkbox为例:
package ld.test;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;
publicclass MyListAdapter extends BaseAdapter {
private Context context;
private String[] list;
private Map<Integer,Integer> selected;
public MyListAdapter(Context context,String[] list){
this.context=context;
this.list=list;
selected=new HashMap<Integer,Integer>();
}
privateclass ViewHolder{
TextView text;
CheckBox check;
}
@Override
publicint getCount() {
// TODO Auto-generated method stub
returnlist.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
returnlist[position];
}
@Override
publiclong getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view=null;
ViewHolder holder=null;
if(convertView==null){
convertView=LayoutInflater.from(context).inflate(R.layout.item, null);
holder=new ViewHolder();
holder.text=(TextView) convertView.findViewById(R.id.text);
holder.check=(CheckBox)convertView.findViewById(R.id.check);
// holder.check.setTag(index);
convertView.setTag(holder);
}
else{
view =convertView;
holder=(ViewHolder)view.getTag();
}
holder.text.setText(list[position]);
holder.check.setTag(position);
if(selected.containsKey(position))
holder.check.setChecked(true);
else
holder.check.setChecked(false);
addListener(holder,position);//添加事件响应
return convertView;
}
privatevoid addListener(ViewHolder holder,finalint position){
holder.check.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
publicvoid onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked){
if(!selected.containsKey(buttonView.getTag()))
selected.put((Integer) buttonView.getTag(),position);
}
else{
selected.remove((Integer) buttonView.getTag());
}
}
});
}
}
这样一来无论你怎么滑动都不会相互干扰了。
效果图如下:
效果图
转自:http://www.eoeandroid.com/blog-576315-1014.html
问: //添加并且显示
list.setAdapter(adapter);
OnItemClickListener listener = null;
list.setOnItemClickListener(listener);
}
public void onItemClick(ListView l, View v, int position, long id) {
Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
//编辑 联系人
startActivity(new Intent(Intent.ACTION_EDIT, uri));
}
部分代码如上,但是点击Item的时候无反映,为什么呢
界面是一个textview,AutoCompleteTextView(用于输入查找联系人信息) 下面是一个LISTVIEW 用于显示符合当前查找条件的联系人列表 (如姓氏等)
答: //添加并且显示
list.setAdapter(adapter);
OnItemClickListener listener = null;
list.setOnIt ...你的listener为null啊,肯定没反应啊