本人原创!解决安卓ListView复用问题最简单的两种方法。

        ListView在安卓很多地方需要用得到,其实listview是基于MVC架构设计的,即数据model,视图view和控制器controller。安卓已帮我们写好该框架,我们只需往里面塞数据就行。对于一些简单的listview,我们常用arrayadapter来作为适配器,但这往往不能达到我们想要的结果,为了界面的功能和美观,我们往往需要自定义适配器。而适配器的基类baseadapter安卓已帮我们写好,我们只需继承该类,实现里面的方法即可。

    那么问题来了,安卓已帮我们设计好的适配器,有一个特点,就是会复用listview中每一个item所对应的view。这是什么意思呢?简单说就是如果你的listview中的item比较多,超出了屏幕,那么系统就会保存你当前显示在屏幕中的listview的item所对应的view对象,当你listview滑动的时候,屏幕外边滑进来的item所对应的view对象是之前系统所保存好的对象,这样的作用是起到一个缓冲的效果,使得资源得到最大化利用,性能得到最大化的优化。
    虽然重用可以使资源最大化利用,但是也带来了一些问题。因为重用的view的对象是同一个,所以,当开发者在使用view进行操作的时候回发现,其所对应的重用的view也发生了操作响应。举一个例子,一个listview有四个item,分别是a,b,c,d。其中abc在一个屏幕里面,d在屏幕下。当你滑到d的时候,d就会使用a所对应的view对象来显示。那么当你对a中某一个控件进行点击的时候,b中对应的那个控件也会发生响应,是不是感觉很蛋疼?这都是因为适配器中的getView()方法重用资源的原因。我们来看下代码:
        @Override
public View getView(int position, View convertView, ViewGroup parent) {
         return null;
    }
  listview每显示一个item,该方法就会被调用一次,第一个参数是listview中的索引,第二个参数显示在每一个item上面的view对象。
     若当前listview刚刚被创建,则convertview就需要我们生成,若listview被滑动到第二第三第四。。屏的时候,系统会将第一屏所保存好的view传过来,就是此时的convertView,这就是指listview的重用。
     那对于这种情况,笔者想了两种方法:
     第一种:
    @Override
public View getView(int position, View convertView, ViewGroup parent) {
               //若listview向下滚动,则在listview生成item的view的时候,将view都储存进一个集合    
   if(position+1>viewlist.size()){
LayoutInflater inflater=LayoutInflater.from(context);
convertView=inflater.inflate(R.layout.query_listview_item, null);
viewlist.add(convertView);}
                   //若listview往回滚动,则将集合中存储好的view赋值给convertview。
   else{
    convertView=viewlist.get(position);
   }

                 //下面是一些view的操作,这里不需要看
TextView cardtextview=(TextView) convertView.findViewById(R.id.cardnumbertextview);
TextView nametextview=(TextView) convertView.findViewById(R.id.nametextview);
cardtextview.setText(list.get(position).cardNumber);
nametextview.setText(list.get(position).name);

return convertView;
}

    第二种方法:
      public class QueryListViewAdapter extends BaseAdapter {
public List<CardsData> list;
public Context context;
public List<View> viewlist=new ArrayList<View>();
public View view;
    @SuppressLint("InflateParams") public QueryListViewAdapter(List<CardsData> list,Context context){
      this.list=list;
      this.context=context;
      viewlist=new ArrayList<View>();
      LayoutInflater inflater=LayoutInflater.from(context);
           //list是存放数据的集合,生成和数据个数一样的view,即将所用的item所对应的view都生成好。
      for(int x=0;x<list.size();x++){
      view=inflater.inflate(R.layout.query_listview_item, null);
      TextView cardtextview=(TextView) view.findViewById(R.id.cardnumbertextview);
    TextView nametextview=(TextView) view.findViewById(R.id.nametextview);
    cardtextview.setText(list.get(x).cardNumber);
    nametextview.setText(list.get(x).name);
      viewlist.add(view);
      }
    }
      //然后根据索引来给对应的convertView赋值
      public View getView(int position, View convertView, ViewGroup parent) {
           convertView=viewlist.get(position);
           return convertView;
       }

两种方法的区别:两种方法都能避免重用问题,但是第一种方法只适合对单个item进行操作,第二种方法适合对所有item进行操作,比如说你需要点击一个item的控件,其他所有item的控件也会作出相应,这时需要用第二种方法。
两种方法都是本人原创,若有不正之处,还望指正,谢谢!!!
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值