【Android studio】优化ListView加载数据逻辑

本文探讨了ListView在快速滑动时出现卡顿的原因,主要归因于频繁创建Item对象和执行findViewById()。通过创建ViewHolder类和复用convertView来优化,减少了内存消耗和屏幕渲染的时间,提高了ListView的滑动流畅性。

优化ListView加载数据逻辑

为什么需要优化ListView?

当ListView控件上加载的Item过多并快速滑动该控件时,界面就会出现卡顿的现象,这就是需要优化的原因

出现卡顿的原因

  1. 当滑动屏幕时,不断地创建Item对象。ListView控件在当前屏幕上显示多少个Item,就会在适配器中的getView()方法创建多少Item对象。当滑动ListView控件时,滑出屏幕的Item对象会被销毁,新加载到屏幕上的Item就会创建新的对象,因此快速滑动ListView控件时会不断地对Item对象进行销毁和创建

  2. 不断执行findViewById()方法初始化控件。每创建一个Item对象都需要加载一次Item布局,加载布局时会不断执行findViewById()方法初始化控件。这些操作比较耗费设备(模拟器,手机等设备)的内存并且浪费时间,如果每个Item都需要加载网络图片,加载网络图片是个比较耗时的操作,就会造成程序内存溢出的异常。

demo代码如下:

public View getView(int position,View convertView,ViewGroup parent){
            View view=View.inflate(MainActivity.this,R.layout.list_item,null);
            TextView title=(TextView)view.findViewById(R.id.title);
            TextView price=(TextView)view.findViewById(R.id.price);
            ImageView iv=(ImageView)view.findViewById(R.id.iv);
            title.setText(titles[position]);
            price.setText(prices[position]);
            iv.setBackgroundResource(icons[position]);
            return view;
        }

优化过程
由于上述两点原因,我们需要对ListView控件进行优化,优化目的是使ListView控件在快速滑动时不再重复创建Item对象,减少内存的消耗和屏幕渲染的处理

  1. 创建ViewHolder类,在MainActivity中创建一个ViewHolder类,将需要加载的控件变量放在该类中
class ViewHolder{
            TextView title,price;
            ImageView iv;
        }
  1. 在getView(int position,View convertView,ViewGroup parent)方法中,第二个参数convertView代表的就是之前滑出屏幕的Item对象。如果第一次加载getView()方法时,会创建Item对象,当滑动ListView控件时,滑出屏幕的Item对象会以缓存的形式存在,而convertView代表的就是缓存的Item对象,我们可以通过复用convertView对象从而减少Item对象的创建,在getView()方法中进行优化的具体代码如下
public View getView(int position,View convertView,ViewGroup parent){
            ViewHolder holder=null;
            if (convertView==null){
                convertView=View.inflate(MainActivity.this,R.layout.list_item,null);
                holder=new ViewHolder();
                holder.title=(TextView)convertView.findViewById(R.id.title);
                holder.price=(TextView)convertView.findViewById(R.id.price);
                holder.iv=(ImageView)convertView.findViewById(R.id.iv);
                convertView.setTag(holder);
            }else {
                holder=(ViewHolder)convertView.getTag();
            }
            holder.title.setText(titles[position]);
            holder.price.setText(prices[position]);
            holder.iv.setBackgroundResource(icons[position]);
            return convertView;
        }

上诉代码中,第2~19行代码主要用于判断convertView(复用视图)对象是否为null,如果为null,则会创建ViewHolder类的对象holder,并将获取的界面控件赋值给ViewHolder类中的属性,最后通过setTag()方法将对象holder添加到convertView对象中,否则,不会创建ViewHolder类中的对象,会通过getTag()方法获取缓存在convertView对象中的ViewHolder类的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值