android自定义listview,添加监听器,解决屏幕滑动组件状态干扰的问题checkbox

来源:互联网 发布:电脑快捷键软件 编辑:程序博客网 时间:2024/05/01 21:37

问题描述:

我在进行android开发的过程中经常使用listview来显示数据,但是listview中的数据不是传统意义上的文字或图片,往往会有其他ui组件,而且还要根据需要为它们添加事件监听器,这个时候就需要自定义listview的适配器然后重载里面的getview()方法了。

Getview()方法是baseadapter里面一个重要的方法,它是在android显示listview里面的内容的时候回调的一个方法。下面就讲讲这个方法的工作机制(个人观点,如有不对,望指出)现在假设我们有10项内容要显示,但是一屏只能显示5项,那么android会首先创建6项对应的itemview的实例并缓存起来,当滑动屏幕,第一项还未移除屏幕,然后第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.itemnull);

                  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;

 

public class 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>();

      }

      private class ViewHolder{

            TextView text;

            CheckBox check;

      }

      @Override

      public int getCount() {

            // TODO Auto-generated method stub

            return list.length;

      }

 

      @Override

      public Object getItem(int position) {

            // TODO Auto-generated method stub

            return list[position];

      }

 

      @Override

      public long 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.itemnull);

                  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;

      }

 

      private void addListener(ViewHolder holder,final int position){

            holder.check.setOnCheckedChangeListener(new OnCheckedChangeListener(){

 

                  @Override

                  public void 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());

                        }

                  }

                 

            });

      }

}

这样一来无论你怎么滑动都不会相互干扰了。

效果图如下:

原创粉丝点击