ListView常用优化技巧

来源:互联网 发布:手机关闭蜂窝移动数据 编辑:程序博客网 时间:2024/05/15 18:59

虽然5.0以后,ListView有被RecyclerView取代的趋势,但是ListView的使用范围依然非常广泛。下面就如何优化ListView与如何实现ListView的多布局。

ViewHolder是提高ListView效率的一个很重要的方法。ViewHolder模式充分利用了ListView的视图缓存机制,避免了每次getView()都通过findViewById()来实例化控件。

针对很多新闻页面,服务器端会随时更新json数据,而且布局也会随之变化,为此多布局的List View随之产生。多布局的ListView主要是运用getViewTypeCount()与getItemViewType(int position)两个方法来实现。只要主要到type与position与数据源中的position,就能很好的实现。

首先,layout布局文件

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:orientation="vertical">    <com.mark.androidheros.widget.CustomListView        android:id="@+id/lv"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:divider="@android:color/darker_gray"        android:dividerHeight="8dp"        android:listSelector="@android:color/transparent"        android:scrollbars="none">    </com.mark.androidheros.widget.CustomListView></FrameLayout>
这里我是自定义了ListView,如果没用特殊要求,可以直接运用原生态的ListView。在布局文件中设置了Item之间的分割线,点击时的效果显示,以及滚动条的隐藏这些属性。

为了提高性能使用ViewHolder,为了实现多布局,重写了getViewTypeCount()与getItemViewType(int position)两个方法,当然ListView中,为了实现显示,我们需要自定义Adapter,其中常用的几个方法也必须要重写的。

public class ViewHolderAdapter extends BaseAdapter {    private static final int VIEW_COUNT = 3;    public static final int IMG_1 = 0;    public static final int IMG_2 = 1;    public static final int IMG_3 = 2;    private Context mContext;    private List<NewsBean.ResultBean.DataBean> mData;    public ViewHolderAdapter(Context context, List<NewsBean.ResultBean.DataBean> data) {        this.mContext = context;        this.mData = data;    }    @Override    public int getCount() {        if (mData != null) {            return mData.size();        }        return 0;    }    @Override    public Object getItem(int position) {        if (mData != null) {            return mData.get(position);        }        return null;    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public int getItemViewType(int position) {        if (mData.get(position) == null) {            return -1;        }        if (!TextUtils.isEmpty(mData.get(position).thumbnail_pic_s03)) {            return IMG_3;        } else {            if (!TextUtils.isEmpty(mData.get(position).thumbnail_pic_s02)) {                return IMG_2;            } else {                return IMG_1;            }        }    }    @Override    public int getViewTypeCount() {        return VIEW_COUNT;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder1 holder1 = null;        ViewHolder2 holder2 = null;        ViewHolder3 holder3 = null;        int type = getItemViewType(position);        if (convertView == null) {            switch (type) {                case IMG_1:                    convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item1_news, parent, false);                    holder1 = new ViewHolder1();                    holder1.pic = (ImageView) convertView.findViewById(R.id.item1_img);                    holder1.title = (TextView) convertView.findViewById(R.id.item1_title);                    holder1.author = (TextView) convertView.findViewById(R.id.item1_author);                    holder1.date = (TextView) convertView.findViewById(R.id.item1_date);                    convertView.setTag(holder1);                    break;                case IMG_2:                    convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item2_news, parent, false);                    holder2 = new ViewHolder2();                    holder2.pic1 = (ImageView) convertView.findViewById(R.id.item2_img1);                    holder2.pic2 = (ImageView) convertView.findViewById(R.id.item2_img2);                    holder2.title = (TextView) convertView.findViewById(R.id.item2_title);                    holder2.author = (TextView) convertView.findViewById(R.id.item2_author);                    holder2.date = (TextView) convertView.findViewById(R.id.item2_date);                    convertView.setTag(holder2);                    break;                case IMG_3:                    convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item3_news, parent, false);                    holder3 = new ViewHolder3();                    holder3.pic1 = (ImageView) convertView.findViewById(R.id.item3_img1);                    holder3.pic2 = (ImageView) convertView.findViewById(R.id.item3_img2);                    holder3.pic3 = (ImageView) convertView.findViewById(R.id.item3_img3);                    holder3.title = (TextView) convertView.findViewById(R.id.item3_title);                    holder3.author = (TextView) convertView.findViewById(R.id.item3_author);                    holder3.date = (TextView) convertView.findViewById(R.id.item3_date);                    convertView.setTag(holder3);                    break;            }        } else {            switch (type) {                case IMG_1:                    holder1 = (ViewHolder1) convertView.getTag();                    break;                case IMG_2:                    holder2 = (ViewHolder2) convertView.getTag();                    break;                case IMG_3:                    holder3 = (ViewHolder3) convertView.getTag();                    break;            }        }        // 设置数据        NewsBean.ResultBean.DataBean data = mData.get(position);        switch (type) {            case IMG_1:                Picasso.with(mContext).load(data.thumbnail_pic_s).centerCrop().fit().priority(Picasso.Priority.HIGH).into(holder1.pic);                holder1.title.setText(data.title);                holder1.author.setText("新闻来源: " + data.author_name);                holder1.date.setText("时间: " + data.date);                break;            case IMG_2:                holder2.title.setText(data.title);                Picasso.with(mContext).load(data.thumbnail_pic_s).centerCrop().fit().priority(Picasso.Priority.HIGH).into(holder2.pic1);                Picasso.with(mContext).load(data.thumbnail_pic_s02).centerCrop().fit().priority(Picasso.Priority.HIGH).into(holder2.pic2);                holder2.author.setText("新闻来源: " + data.author_name);                holder2.date.setText("时间: " + data.date);                break;            case IMG_3:                holder3.title.setText(data.title);                Picasso.with(mContext).load(data.thumbnail_pic_s).centerCrop().fit().priority(Picasso.Priority.HIGH).into(holder3.pic1);                Picasso.with(mContext).load(data.thumbnail_pic_s02).centerCrop().fit().priority(Picasso.Priority.HIGH).into(holder3.pic2);                Picasso.with(mContext).load(data.thumbnail_pic_s03).centerCrop().fit().priority(Picasso.Priority.HIGH).into(holder3.pic3);                holder3.author.setText("新闻来源: " + data.author_name);                holder3.date.setText("时间: " + data.date);                break;        }        return convertView;    }    // 只有一张图片时    class ViewHolder1 {        public ImageView pic;        public TextView title;        public TextView author;        public TextView date;    }    // 两张图片时    class ViewHolder2 {        public ImageView pic1;        public ImageView pic2;        public TextView title;        public TextView author;        public TextView date;    }    // 三张图片时    class ViewHolder3 {        public ImageView pic1;        public ImageView pic2;        public ImageView pic3;        public TextView title;        public TextView author;        public TextView date;    }}
这里我们自定义ViewHolderAdapter继承自BaseAdapter。显示了3种不同的布局。根据数据源,自定义了3个type。

其他,关于Android下的网络编程,我们使用了Volley作为网络访问,使用Picasso作为图片的处理,另外还可以结合LruCache技术,自定义CacheBitmap,针对图片,每次取缓存图片,从而避免OOM。

源代码可以参考: https://github.com/dengwenxue/AndroidHeros

敲了这么多,如果觉得还不错,请给个赞。

































0 0