使用Xutils框架优化ListView

对listView的优化相信搞android的都不陌生.

目前优化ListView的方法主要有以下几种:

1,使用ConvertView接收inflate的布局

2,使用ViewHolder管理布局的控件

一般代码如下:

...
 final ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_listview_layout, null);
            holder.imageView = (ImageView) convertView.findViewById(R.id.image);
            holder.textView = (TextView) convertView.findViewById(R.id.text);

            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }
...

这种方式优化ListView很常见,同时也能大幅提升ListView的性能.

但是,当ListView里包含图片同时图片又是实时从网络获取的情况下,只采用上面两种方式显然不够,

如果在滑动的时候同时加载图片的话,会造成很大的性能消耗和资源浪费,并且加载完毕之后图片往往会错位,且滑动起来相当卡顿,造成非常差的用户体验,为了避免图片错位,有些文章里建议在加载图片的时候,给ImageView设置一个tag,tag内容一般为当前图片的url,然后再去联网获取图片,当获取到图片之后,在根据之前设置的tag找到对应的ImageView,然后设置图片,这样固然可以避免图片错位问题,但是却不能解决滑动卡顿问题,所以第3种优化方法就是:滑动不加载

3,listView滑动时不加载图片

这是一种很好 的策略,可以有效减少listView滑动时的卡顿,要做到滑动时不加载,只要监听ListView的onScrollListener,当滑动状态为onScroll或者onFiling时,不加载图片,当滑动状态为idle时,再加载图片,思路是这样的没错,但是真正做起来却没这么简单,首先,一般我们的Adapter是单独写一个类的,而onScrollListener是在其他activity的,我们不好控制在滑动的时候不让listView 的item进行网络连接,虽然我们可以在Adapter里设置一个flag,然后在onScrollListener里判断,当滑动的时候让这个flag置为false,然后在adapter的getView方法中判断,如果flag是false就不加载图片,否则就加载图片,但是这样做太麻烦,并且有一个不足,就是listView刚显示出来时,滑动状态不是idle,这就导致了listView刚显示出来时,不会加载任何image的url,我们还得再处理这种情况,麻烦程度又上升一层,就算上面说的情况都处理好了,还有一个问题,就是图片缓存,

4,图片缓存

图片缓存同样可以有效减少滑动时的卡顿,所以我们又得对图片做缓存,然后在getView方法里再加一些获取缓存图片的判断,ok,就算我们做好了缓存,也做好了判断,但是如果getView方法里的if语句过多,在加载item时要依次判断多个if语句,这在item的加载速度上又打了折扣,而加载速度和listView的性能是紧密相关的,所以如果滑动不加载处理不好的话,也是不行的.

5,对图片大小进行固定

在图片显示到ImageView之前,要把图片缩放到一个合适的大小上,尽量不让ImageView去缩放图片,这一点我们应该很熟悉,比如腾讯新闻,网易新闻等新闻客户端,他们的ImageView显示出来的图片大小都是一样的,一方面是好看,另一个更主要的原因就是可以提高listView 的加载性能,所以我们在获取到图片之后要对图片进行缩放,缩放到一个合适的大小之后再显示出来,这样又会更加麻烦.

上述5种方法算是目前比较主流的优化Listview的方法,当然还有一些其他细节上的优化,这里就不说了,这5种方法一般会同时用到,当然前提是得加载网络图片,

但是这5种方式都实现,自己做起来也太麻烦了,并且封装性很差,如果其他地方用到类似的方法,还得复制过去再修改,这会让程序的耦合性很高,不利于后期的代码管理.

而采用Xutils框架提供 的方法则可以省去第3步,第4步,第5步这些繁琐的方法,只要几行代码就能搞定,而第1步和第2步我们自己实现起来又很简单,这样ListView的优化瞬间就能完成,并且Xutils框架已经给我们封装好了方法,可以很方便的移植到其他地方,大大降低了程序的耦合性.

ok,说了这么多,我们来看看使用Xutils框架优化ListView到底有多简单:

MyAdapter代码:

package com.rqq.optimizelistview.adapters;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.lidroid.xutils.BitmapUtils;
import com.lidroid.xutils.bitmap.BitmapDisplayConfig;
import com.lidroid.xutils.bitmap.core.BitmapSize;
import com.rqq.optimizelistview.R;
import com.rqq.optimizelistview.beans.NewsInfo;

import java.util.List;


public class myAdapter extends BaseAdapter {

    private Context mContext;
    private List<NewsInfo> mList;
    public BitmapUtils bitmapUtils;

    public myAdapter(Context context, List<NewsInfo> list, BitmapUtils utils) {
        this.mContext = context;
        this.mList = list;
        this.bitmapUtils = utils;

    }

    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_listview_layout, null);
            holder.imageView = (ImageView) convertView.findViewById(R.id.image);
            holder.textView = (TextView) convertView.findViewById(R.id.text);

            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.textView.setText(mList.get(position).getText());
        //1,实例化BitmapDisplayConfig
        BitmapDisplayConfig config = new BitmapDisplayConfig();
        //2,设置bitmapConfig
        config.setBitmapConfig(Bitmap.Config.RGB_565);
        //3,设置加载失败时显示的图片
        config.setLoadFailedDrawable(mContext.getResources().getDrawable(R.mipmap.ic_launcher));
        //4,设置正在加载时显示的图片
        config.setLoadingDrawable(mContext.getResources().getDrawable(R.mipmap.ic_launcher));
        //5,设置图片的最大宽高
        config.setBitmapMaxSize(new BitmapSize(100, 100));
        //6,设置disk缓存开启,图片会缓存到sd卡,即DiskLruCache
        bitmapUtils.configDiskCacheEnabled(true);
        //7,设置Memory缓存开启,即LruCache
        bitmapUtils.configMemoryCacheEnabled(true);
        //8,根据上面设置的条件展示图片
        bitmapUtils.display(holder.imageView, mList.get(position).getUrl(), config);
        return convertView;
    }

    static class ViewHolder {
        TextView textView;
        ImageView imageView;
    }
}


这里需要注意,一定要先配置第6步的Disk缓存再配置第7步的Lru缓存,如果颠倒顺序,Lru的缓存起不到效果,它会直接读取disk缓存而不读取Lru缓存.,这估计是Xutils的一个小bug,

MainActivity代码:

package com.rqq.optimizelistview.activities;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;

import com.lidroid.xutils.BitmapUtils;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.rqq.optimizelistview.R;
import com.rqq.optimizelistview.adapters.myAdapter;
import com.rqq.optimizelistview.beans.NewsInfo;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private myAdapter adapter;
    private List<NewsInfo> list = new ArrayList<>();
    private BitmapUtils bitmapUtils;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        list.add(new NewsInfo("图片1", "http://d.hiphotos.baidu.com/image/pic/item/2e2eb9389b504fc2065e2bd2e1dde71191ef6de0.jpg"));
        list.add(new NewsInfo("图片2", "http://h.hiphotos.baidu.com/image/pic/item/b03533fa828ba61e574f53f84534970a314e5940.jpg"));
        list.add(new NewsInfo("图片3", "http://h.hiphotos.baidu.com/image/pic/item/dbb44aed2e738bd4ec4f29e6a58b87d6267ff9ff.jpg"));
        list.add(new NewsInfo("图片4", "http://g.hiphotos.baidu.com/image/pic/item/f11f3a292df5e0fe7f5e12d6586034a85fdf72a7.jpg"));
        list.add(new NewsInfo("图片5", "http://c.hiphotos.baidu.com/image/pic/item/1f178a82b9014a90a47fdd6aad773912b21beea0.jpg"));
        list.add(new NewsInfo("图片6", "http://e.hiphotos.baidu.com/image/pic/item/7af40ad162d9f2d32378bf38adec8a136227ccf8.jpg"));
        list.add(new NewsInfo("图片7", "http://h.hiphotos.baidu.com/image/pic/item/d4628535e5dde71147bbd821a3efce1b9c1661f8.jpg"));
        list.add(new NewsInfo("图片8", "http://g.hiphotos.baidu.com/image/pic/item/5fdf8db1cb134954e75e73b3524e9258d0094aa1.jpg"));
        list.add(new NewsInfo("图片9", "http://d.hiphotos.baidu.com/image/pic/item/1e30e924b899a9012776c0e119950a7b0308f5a2.jpg"));
        list.add(new NewsInfo("图片10", "http://b.hiphotos.baidu.com/image/pic/item/d058ccbf6c81800ae0a612d9b53533fa838b47a2.jpg"));
        list.add(new NewsInfo("图片11", "http://b.hiphotos.baidu.com/image/pic/item/aec379310a55b319a28419a247a98226cefc17e3.jpg"));
        list.add(new NewsInfo("图片12", "http://b.hiphotos.baidu.com/image/pic/item/0df3d7ca7bcb0a4663a610ee6f63f6246a60af65.jpg"));
        list.add(new NewsInfo("图片13", "http://c.hiphotos.baidu.com/image/pic/item/a71ea8d3fd1f4134954b9ea9211f95cad0c85eec.jpg"));
        list.add(new NewsInfo("图片14", "http://h.hiphotos.baidu.com/image/pic/item/d788d43f8794a4c2629f7cfc0af41bd5ac6e39ac.jpg"));
        list.add(new NewsInfo("图片15", "http://d.hiphotos.baidu.com/image/pic/item/8b13632762d0f703ead80e0b0cfa513d2797c5fb.jpg"));
        list.add(new NewsInfo("图片16", "http://g.hiphotos.baidu.com/image/pic/item/6609c93d70cf3bc79165563bd500baa1cc112afb.jpg"));
        list.add(new NewsInfo("图片17", "http://b.hiphotos.baidu.com/image/pic/item/7a899e510fb30f2493c8cbedcc95d143ac4b0389.jpg"));
        list.add(new NewsInfo("图片18", "http://e.hiphotos.baidu.com/image/pic/item/7aec54e736d12f2ed548898e4bc2d5628435688a.jpg"));
        list.add(new NewsInfo("图片19", "http://e.hiphotos.baidu.com/image/pic/item/241f95cad1c8a7866dcb6de06309c93d71cf507e.jpg"));
        list.add(new NewsInfo("图片20", "http://e.hiphotos.baidu.com/image/pic/item/dcc451da81cb39db722040b8d4160924aa18307f.jpg"));
        list.add(new NewsInfo("图片21", "http://d.hiphotos.baidu.com/image/pic/item/42a98226cffc1e17615cabdf4e90f603728de979.jpg"));
        list.add(new NewsInfo("图片22", "http://a.hiphotos.baidu.com/image/pic/item/fc1f4134970a304e858e8714d5c8a786c8175cab.jpg"));
        list.add(new NewsInfo("图片23", "http://d.hiphotos.baidu.com/image/pic/item/e850352ac65c103818d1e92cb6119313b17e89b4.jpg"));
        list.add(new NewsInfo("图片24", "http://d.hiphotos.baidu.com/image/pic/item/42a98226cffc1e176110abdf4e90f603728de9b5.jpg"));
        list.add(new NewsInfo("图片25", "http://d.hiphotos.baidu.com/image/pic/item/562c11dfa9ec8a13f075f10cf303918fa1ecc0eb.jpg"));
        list.add(new NewsInfo("图片26", "http://f.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f735600bfe760e0cf3d6cad6cb.jpg"));
        list.add(new NewsInfo("图片27", "http://d.hiphotos.baidu.com/image/pic/item/cb8065380cd7912344a13298a9345982b3b7809d.jpg"));
        list.add(new NewsInfo("图片28", "http://a.hiphotos.baidu.com/image/pic/item/8601a18b87d6277f1ee195d42c381f30e824fc6f.jpg"));
        list.add(new NewsInfo("图片29", "http://d.hiphotos.baidu.com/image/pic/item/83025aafa40f4bfba09238b8074f78f0f636189f.jpg"));
        list.add(new NewsInfo("图片30", "http://c.hiphotos.baidu.com/image/pic/item/d788d43f8794a4c2474741c70af41bd5ac6e39f1.jpg"));
        list.add(new NewsInfo("图片31", "http://b.hiphotos.baidu.com/image/pic/item/4a36acaf2edda3cc9de31ecc05e93901203f92d3.jpg"));
        list.add(new NewsInfo("图片32", "http://f.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee0d44a9f529f5e0fe98257efc.jpg"));
        list.add(new NewsInfo("图片33", "http://h.hiphotos.baidu.com/image/pic/item/b7fd5266d0160924ec4504f7d00735fae7cd34fd.jpg"));
        list.add(new NewsInfo("图片34", "http://f.hiphotos.baidu.com/image/pic/item/a71ea8d3fd1f41348a8ca392211f95cad0c85ea6.jpg"));
        list.add(new NewsInfo("图片35", "http://e.hiphotos.baidu.com/image/pic/item/8cb1cb134954092359d94e479758d109b3de4952.jpg"));
        list.add(new NewsInfo("图片36", "http://h.hiphotos.baidu.com/image/pic/item/d50735fae6cd7b8959dc17ba0a2442a7d9330e52.jpg"));
        list.add(new NewsInfo("图片37", "http://c.hiphotos.baidu.com/image/pic/item/a044ad345982b2b782d814fd34adcbef76099b47.jpg"));
        list.add(new NewsInfo("图片38", "http://e.hiphotos.baidu.com/image/pic/item/8cb1cb1349540923592e4e479758d109b3de4947.jpg"));
        list.add(new NewsInfo("图片39", "http://c.hiphotos.baidu.com/image/pic/item/4034970a304e251f0f44c9c1a286c9177f3e5353.jpg"));
        list.add(new NewsInfo("图片40", "http://e.hiphotos.baidu.com/image/pic/item/ac6eddc451da81cb851baef45766d0160924310d.jpg"));
        list.add(new NewsInfo("图片41", "http://e.hiphotos.baidu.com/image/pic/item/14ce36d3d539b600be63e95eed50352ac75cb7ae.jpg"));
        list.add(new NewsInfo("图片42", "http://g.hiphotos.baidu.com/image/pic/item/03087bf40ad162d9ec74553b14dfa9ec8a13cd7a.jpg"));
        list.add(new NewsInfo("图片43", "http://g.hiphotos.baidu.com/image/pic/item/8c1001e93901213fcea979fb51e736d12f2e957a.jpg"));
        list.add(new NewsInfo("图片44", "http://a.hiphotos.baidu.com/image/pic/item/4b90f603738da97739bab10cb551f8198618e37b.jpg"));
        //9
        bitmapUtils = new BitmapUtils(this);

        listView = (ListView) findViewById(R.id.listView);
        adapter = new myAdapter(this, list, bitmapUtils);
        listView.setAdapter(adapter);
        //10,滑动时不加载,一定要new PauseOnScrollListener监听
        //第一个参数为bitmapUtils对象,第二个参数为滑动状态为OnScroll时是否暂停加载图片
        //第三个参数为滑动状态为OnFiling时是否暂停加载图片
        listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils, true, true));
    }
}

ok,代码就这么多,数一下,所有关于Xutils的代码加起来才10行,就完成了第3,4,5步的功能,是不是很简单,如果自己写的话,代码量估计扩大10倍都不止,

不懂的请留言,看到就会回复

如果这篇文章对你有帮助,请点个赞吧~~




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值