列表优化

来源:互联网 发布:holy cross学院知乎 编辑:程序博客网 时间:2024/06/16 21:58

        实际开发过程当中,我遇到了这样的问题,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开启硬件加速。

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

       


0 0