列表优化

本文介绍了一种优化Android ListView性能的方法,通过监听ListView滚动状态并延迟执行异步任务,避免了大量UI更新导致的卡顿问题。此外,还提到了开启硬件加速作为额外优化手段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        实际开发过程当中,我遇到了这样的问题,listview一个item里面有一个大的banner图,banner图上又盖了个10%透明度的蒙层(为了如果banner图是白色的那种,让标题的字显示出来),还盖了各种各样的图(要根据类别判断显示或隐藏),底下还有很多标题,按钮,还包括两个自定义的viewgroup(在adapter里面不断的往布局里填充或者移除控件),等等等等。。。。

相信这种需求在Android开发中还是很常见的,列表的优化问题就很重要了。

       当然adapter要用viewholder来写,充分利用listview的缓存机制,然后在getView()方法里写咯,在getView里尽量采用异步处理咯,但是这往往还是不够的。Android机器实在太多了,性能上的差异性也有很大的区别,所以在有些机器上,卡顿现象还是会存在的。

       那应该怎么办呢?其实大家都知道,getView()方法里面不能执行耗时操作,就比如加载图片什么的,必须采用异步来解决,imageLoader就是个很好的方法。但是因为异步的东西多了,就会出现这么一个情况,如果用户刻意地频繁地上下滑动,就会在一瞬间产生大量的异步任务,这么多的异步任务就会造成线程池的拥堵以及带来大量的UI更新的操作,而这些UI更新的操作都是在主线程上操作的,所以就会出现一定程度的卡顿现象了。

所以,要解决这个问题,可以考虑在列表滑动的时候不去做那些异步任务,等列表停下来的时候再去操作这些异步任务,这样子操作的话仍然可以获得良好的用户体验。

具体代码操作我就举一个简单的例子,Adapter里是这样的,为了简化操作,item里面只有一个textView的,在这里假设textView的setText()就是个异步处理,adapter的代码如下:

public class ListAdapter extends BaseAdapter{

    private List<String> stringList;
    private Context context;
    private LayoutInflater layoutInflater;

    private ListView listView;
    private boolean isListViewIdle = true;

    public ListAdapter(List<String> stringList,Context context,ListView listView){
        this.context = context;
        layoutInflater = LayoutInflater.from(context);
        this.stringList = stringList;
        this.listView = listView;
        this.listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                isListViewIdle = true;
                if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE){
                    updateUI();
                }else {
                    isListViewIdle = false;
                }
            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i1, int i2) {

            }
        });
    }

    private void updateUI() {
        this.notifyDataSetChanged();
    }

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

    @Override
    public Object getItem(int i) {
        return stringList.get(i);
    }

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if (viewHolder == null){
            view = layoutInflater.inflate(R.layout.item,viewGroup,false);
            viewHolder = new ViewHolder();
            viewHolder.textView = (TextView)view.findViewById(R.id.text);

            view.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder)view.getTag();
        }
        if (isListViewIdle){
            viewHolder.textView.setText(stringList.get(i));
        }else {
            viewHolder.textView.setText("加载中………");
        }

        return view;
    }

    class ViewHolder{
        TextView textView;
    }
}

在adapter里我把listview传递了进来,让listview实现onScollListener,在onScrollListener里面监听listView的滑动现在是静止的还是在滑动的,滑动的话,就给textView设置“加载中”(就是显示默认的东西,这里同样做了简化),静止的时候 加载数据。在Activity就是简单的listView.setAdapter.........

但是以上操作我在pulltorefreshListView里也进行了试验,却没有达到想要的效果,设置了onScrollListener以后,就无法上拉加载,产生冲突了,这个问题,我还得看一下,看看有没有好的解决的办法。

这样子操作,正常的ListView和GridView,如果一个item里面有很多异步任务的时候性能上就得到了提升。在网上找资料的时候,我还发现了这个,在某些特殊情况下,列表还是会有偶尔的卡顿现象,这个时候还可以开启硬件加速。绝大多数情况下,硬件加速都可以解决莫名的卡顿问题,通过设置android:hardwareAccelerated=“true”即可为Activity开启硬件加速。

以上方法就是我对这个问题所想到的优化的方法,如果各位大神还有其他更好的方法的,留言给我下思路吧!!!谢谢!!!

 

       

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值