ListView的性能优化之convertView和viewHolder

来源:互联网 发布:招聘网络主播 编辑:程序博客网 时间:2024/06/05 16:19

ListView优化大致从以下几个角度:
1.复用已经生成的convertView;
2.添加viewHolder类;
3.缓存数据(图片缓存);
4.分页加载。

一、复用convertView
首先讲下ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView的方法,这个方法会传入一个convertView的参数,返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存,创建View对象(mInflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)也是耗时操作,所以必将影响性能。Android提供了一个叫做Recycler(反复循环器)的构件,就是当ListView的Item从上方滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,相应的会从下方生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的Item的View,所以说如果能重用这个convertView,就会大大改善性能。

这连个超链接需要看看 ,写的比较好
http://www.cnblogs.com/itstudent/p/3729117.html
http://blog.csdn.net/jacman/article/details/7087995

这是我做的程序测试:
这里写图片描述

看代码:

package com.example.mypic;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.widget.ListView;public class MainActivity extends Activity {    private ListView listView;    private MyAdapter adapter;    private int[] items = new int[] { R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,            R.drawable.pc, R.drawable.pc };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        listView = (ListView) findViewById(R.id.listView);        Log.v("aa", "--显示图片-1-");        adapter = new MyAdapter(this, items);        Log.v("aa", "--显示图片-2-");        listView.setAdapter(adapter);        Log.v("aa", "--显示图片-3-");        adapter.notifyDataSetChanged();    }}
package com.example.mypic;import android.content.Context;import android.graphics.Bitmap;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;public class MyAdapter extends BaseAdapter {    private int[] items = new int[] {};    private Context context;    private String TAG = "aa";    private Bitmap bitmap = null;    public MyAdapter(Context context, int[] items) {        this.context = context;        this.items = items;    }    @Override    public int getCount() {        return items.length;    }    @Override    public Object getItem(int position) {        return items[position];    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        //Log.v(TAG, "position=="+position);        //Log.v(TAG, "convertView=="+convertView);        //Log.v(TAG, "ViewGroup=="+parent);        ViewHolder holder;        if (convertView == null) {            convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);            holder = new ViewHolder();            holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);            holder.textView = (TextView) convertView.findViewById(R.id.textView);            Log.v(TAG, position+"----"+holder);            convertView.setTag(holder);        }else {            holder = (ViewHolder) convertView.getTag();            Log.v(TAG, position+"--1--"+holder);        }        bitmap = BitmapCompressTools.decodeSampledBitmapFromResource(                    context.getResources(), R.drawable.pc, 100, 100);        //Log.d(TAG, "压缩之后的图片大小为:" + bitmap.getByteCount());        holder.imageView.setImageBitmap(bitmap);        holder.textView.setText("图片"+position);        return convertView;    }    class ViewHolder {        ImageView imageView;        TextView textView;    }}
package com.example.mypic;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class BitmapCompressTools {    public static Bitmap decodeSampledBitmapFromResource(Resources res,            int resId, int reqWidth, int reqHeight) {        // 给定的BitmapFactory设置解码的参数        final BitmapFactory.Options options = new BitmapFactory.Options();        // 从解码器中获取原始图片的宽高,这样避免了直接申请内存空间        options.inJustDecodeBounds = true;        BitmapFactory.decodeResource(res, resId, options);        // Calculate inSampleSize        options.inSampleSize = calculateInSampleSize(options, reqWidth,                reqHeight);        // 压缩完后便可以将inJustDecodeBounds设置为false了。        options.inJustDecodeBounds = false;        return BitmapFactory.decodeResource(res, resId, options);    }    /**     * 指定图片的缩放比例     *      * @param options     * @param reqWidth     * @param reqHeight     * @return     */    public static int calculateInSampleSize(BitmapFactory.Options options,            int reqWidth, int reqHeight) {        // 原始图片的宽、高        final int height = options.outHeight;        final int width = options.outWidth;        int inSampleSize = 1;//      if (height > reqHeight || width > reqWidth) {//          //这里有两种压缩方式,可供选择。//          /**//           * 压缩方式二//           *///          // final int halfHeight = height / 2;//          // final int halfWidth = width / 2;//          // while ((halfHeight / inSampleSize) > reqHeight//          // && (halfWidth / inSampleSize) > reqWidth) {//          // inSampleSize *= 2;//          // }//                      /**             * 压缩方式一             */            // 计算压缩的比例:分为宽高比例            final int heightRatio = Math.round((float) height                    / (float) reqHeight);            final int widthRatio = Math.round((float) width / (float) reqWidth);            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;//      }        return inSampleSize;    }}

main.ml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <ListView        android:id="@+id/listView"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true" >    </ListView></RelativeLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <ImageView        android:id="@+id/imageView"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"         android:layout_marginLeft="20dp"/></LinearLayout>

这是运行结果图:
这里写图片描述

0 0
原创粉丝点击