[转]ListView学习笔记(一)——缓存机制

本文详细介绍了Android中ListView的工作原理及如何通过复用convertView来优化其性能。解释了ListView如何仅加载屏幕上可见的项以减少内存消耗,并展示了具体的实现代码。

要想优化ListView首先要了解它的工作原理,列表的显示需要三个元素:ListView、Adapter、显示的数据;

这里的Adapter就是用到了适配器模式,不管传入的是什么View在ListView中都能显示出来。

下面简单说下上图的原理:

1、如果你有几千几万甚至更多的选项(item)时,其中只有可见的项目(满屏显示的Item数目)存在内存(说的优化就是说在内存中的优化!)中,其他的在Recycler中

2、ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的,第一次都是为空的,只要显示过了convertView都不为空,会保存在Recycler中

3、当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图,省去了inflate和findViewById的时间,性能就得到了优化。

\

 

了解了它的工作原理后,我们就可以重复利用convertView,只要不为空就直接使用,改变它的内容就行了。

使用ListView的时候都会搭配一个Adapter,为了使得性能更优,ListView会缓存行item(某行对应的View)。ListView通过Adapter的getView函数获得每行的item。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.dzt.listviewdemo;
 
import java.util.ArrayList;
 
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
 
public class MainActivity extends Activity {
 
     private ListAdapter adapter;
     private ListView lv = null ;
     private ArrayList<string> list = new ArrayList<string>();
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         lv = (ListView) findViewById(R.id.lv_list);
         adapter = new ListAdapter();
         for ( int i = 0 ; i < 100 ; i++) {
             list.add(item  + i);
         }
         lv.setAdapter(adapter);
     }
 
     private class ListAdapter extends BaseAdapter {
 
         private LayoutInflater mInflater;
 
         ListAdapter() {
             mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         }
 
         @Override
         public int getCount() {
             // TODO Auto-generated method stub
             return list.size();
         }
 
         @Override
         public Object getItem( int position) {
             // TODO Auto-generated method stub
             return list.get(position);
         }
 
         @Override
         public long getItemId( int position) {
             // TODO Auto-generated method stub
             return position;
         }
 
         @Override
         public View getView( int position, View convertView, ViewGroup parent) {
             // TODO Auto-generated method stub
             System.out.println(getView  + position +      + convertView);
             viewHolder holder = null ;
             if (convertView == null ) {
                 convertView = mInflater.inflate(R.layout.item, null );
                 holder = new viewHolder();
                 holder.text = (TextView) convertView.findViewById(R.id.tv_text);
                 holder.image = (ImageView) convertView
                         .findViewById(R.id.iv_img);
                 convertView.setTag(holder);
             } else {
                 holder = (viewHolder) convertView.getTag();
             }
             holder.text.setText(list.get(position));
             if (position % 2 == 0 ) {
                 holder.image.setImageResource(R.drawable.ic_launcher);
             } else {
                 holder.image.setImageResource(R.drawable.icon);
             }
 
             return convertView;
         }
 
     }
 
     /**
      * 使用一个类来保存Item中的元素
      *
      * @author Administrator
      *
      */
     public static class viewHolder {
         public TextView text;
         public ImageView image;
     }
}
</string></string>

运行效果

 

\


第一次打印的结果convertView都是为null

 

\

滑动ListView后的打印

\

 

 

从上面的打印消息可以看出,Recycler中会保存七个convertView对象用来显示Item,不管你有上千个Item,也只会创建显示满屏的convertView,这就大大节省了内存,对viewHolder的Tag的使用也大大节省了性能开销

转载于:https://www.cnblogs.com/DarrenChan/p/5673004.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值