Android开发优化-Adapter优化

  categories:android资料  author:
来源:http://www.cnblogs.com/purediy/p/3267913.html

ListView 作为Android开发中使用频率最高的一个控件,保证ListView的流畅运行,对用户体验的提高至关重要。Adapter是ListView和数据 源之间的中间人,当每条数据进入可见区时,Adapter 的 getView() 会被调用,返回代表具体数据的视图,在成百上千条数据触摸滚动时频繁调用,因此如何优化Adapter是提高ListView性能的关键。

1. 使用ViewHolder模式,重复利用convertView,减少频繁查找

在2009年 Google IO开发者大会中已做说明,看一下使用不同实现方式之间的差距:

Adapter 显示每条数据的 XML 布局文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
<LinearLayout
    android:orientation="horizontal">
    <ImageView android:id="@+id/icon"
        android:layout_width="48dip"
        android:layout_height="48dip" />
    <TextView android:id="@+id/text"
        android:layout_gravity="center_vertical"
        android:layout_width="0dip"
        android:layout_weight="1.0"
        android:layout_height="wrap_content" />
</LinearLayout>

1. 最慢最不实用的方式

1
2
3
4
5
6
7
8
9
public View getView(int position, View convertView, ViewGroup parent) {
    View item = mInflater.inflate(R.layout.list_item_icon_text, null);
    ((TextView) item.findViewById(R.id.text)).setText(DATA[position]);
    ((ImageView) item.findViewById(R.id.icon)).setImageBitmap(
            (position & 1) == 1 ? mIcon1 : mIcon2);
    return item;
}

2. 使用 convertView 回收视图, 效率提高 200%

1
2
3
4
5
6
7
8
9
10
11
public View getView(int position, View convertView, ViewGroup parent) {
     if (convertView == null) {
          convertView = mInflater.inflate(R.layout.item, null);
     }
     ((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);
     ((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(
               (position & 1) == 1 ? mIcon1 : mIcon2);
     return convertView;
}

3. 使用 ViewHolder 模式, 效率再提高 50%

1
2
3
4
static class ViewHolder {
    TextView text;
    ImageView icon;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public View getView(int pos, View convertView, ViewGroup parent){
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item, null);
        holder = new ViewHolder(); 
        holder.text = (TextView) convertView.findViewById(R.id.text));
        holder.icon = (ImageView) convertView.findViewButId(R.id.icon));
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    
    holder.text.setText(DATA[pos]);
    holder.icon.setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
    return convertView;
}

更新率比较如下图:

QQ截图20130819151124

2. 使用工作线程加载数据,减轻UI主线程负担,使UI主线程只专注于UI绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Using an AsyncTask to load the slow images in a background thread
new AsyncTask<ViewHolder, Void, Bitmap>() {
    private ViewHolder v;
    @Override
    protected Bitmap doInBackground(ViewHolder... params) {
        v = params[0];
        return mFakeImageLoader.getImage();
    }
    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        if (v.position == position) {
            // If this item hasn't been recycled already, hide the
            // progress and set and show the image
            v.progress.setVisibility(View.GONE);
            v.icon.setVisibility(View.VISIBLE);
            v.icon.setImageBitmap(result);
        }
    }
}.execute(holder);

3. 优化item布局,尽量优化子view布局不被过渡重绘,每一点子view的优化都能提高整体的性能

参见 Android开发优化-布局优化



快乐成长 每天进步一点点