android adapter的效能小結

HighFUN發表於2013-08-26

一般adapter的做法會重寫getView方法

比如

 1 @Override
 2     public View getView(int position, View convertView, ViewGroup parent) {
 3         if (convertView == null) {
 4             convertView = LayoutInflater.from(context).inflate(R.layout.contentitem, null);
 5         }
 6         TextView title = (TextView) convertView.findViewById(R.id.textViewTitle);
 7         TextView author = (TextView) convertView.findViewById(R.id.textViewAuthor);
 8         TextView content = (TextView) convertView.findViewById(R.id.textViewContent);
 9         TextView otherInfo = (TextView) convertView.findViewById(R.id.textViewOtherInfo);
10         ImageView contentImage = (ImageView)convertView.findViewById(R.id.imageView);
11         ContentInfo info = data.get(position);
12         title.setText(info.title);
13         author.setText(info.author);
14         content.setText(info.content);
15         otherInfo.setText(info.otherInfo);
16         new HttpImageLoader(contentImage).load(info.imageUri);
17         convertView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
18         return convertView;
19     }

這樣寫有一個問題,就是如果我的圖片比較大,contentImage 的載入時間就會比較長,那麼當你很快的滾動listview的時候,就會重新整理不過來。

為此我做了這樣一個快取

 1 public View getView(int position, View convertView, ViewGroup parent) {
 2         if (convertView == null) {
 3             convertView = LayoutInflater.from(context).inflate(R.layout.contentitem, null);
 4         }
 5 
 6         TextView title = (TextView) convertView.findViewById(R.id.textViewTitle);
 7         TextView author = (TextView) convertView.findViewById(R.id.textViewAuthor);
 8         TextView content = (TextView) convertView.findViewById(R.id.textViewContent);
 9         TextView otherInfo = (TextView) convertView.findViewById(R.id.textViewOtherInfo);
10         ImageView contentImage = (ImageView)convertView.findViewById(R.id.imageView);
11         ContentInfo info = data.get(position);
12         title.setText(info.title);
13         author.setText(info.author);
14         content.setText(info.content);
15         otherInfo.setText(info.otherInfo);
16         new HttpImageLoader(contentImage).load(info.imageUri);
17         convertView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
18 
19         return convertView;
20     }
21 
22     private class HttpImageLoader{
23         private Bitmap bitmap;
24         private ImageView image;
25 
26         final android.os.Handler handler = new android.os.Handler() {
27             @Override
28             public void handleMessage(Message msg) {
29                 super.handleMessage(msg);
30                 image.setImageBitmap(bitmap);
31             }
32         };
33 
34         public HttpImageLoader(ImageView view){
35             image = view;
36         }
37         public void load(String url){
38             final String u = url;
39             if (map.containsKey(url)){
40                 image.setImageBitmap(map.get(url));
41                 return;
42             }
43             new Thread() {
44                 @Override
45                 public void run() {
46                     bitmap = HttpUtil.getHttpBitmap(u);
47                     map.put(u,bitmap);
48                     handler.sendEmptyMessage(0);
49                 }
50             }.start();
51 
52         }
53     }
HttpImageLoader類中,每次載入一個圖片就會將這個圖片快取起來放入到map中,這樣省去了重新從網路讀取的時間。完全是從本地載入。
效果比之前好很多,但是還是會卡。
最後採用了最土的方法。
新增的時候,直接new一個view出來,然後將整個view放入到快取中。
 1     public void add(final ContentInfo info) {
 2         ContentItemView contentItemView  = new ContentItemView(context);
 3         contentItemView.setContentInfo(info);
 4         contentItemView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
 5 
 6         contentItemView.setOnClickListener(new View.OnClickListener() {
 7             @Override
 8             public void onClick(View v) {
 9                 Intent intent = new Intent(context,ArticleActivity.class);
10                 Bundle bundle = new Bundle();
11                 intent.putExtra("info",info);
12                 context.startActivity(intent);
13             }
14         });
15         data.add(contentItemView);
16     }

getView的時候直接從程式碼中將整個view取出來

1     @Override
2     public View getView(int position, View convertView, ViewGroup parent) {
3         return data.get(position);
4     }

這樣雖然比較耗記憶體,但是整個會變得很流暢。

不過如果這樣做的話,還不如直接用Scrollview+linearLayout的組合比較合適。

當然了,前提是我能夠保證在listview中的item不會太多,記憶體的消耗能夠在我的容忍範圍之內,才可以這樣做。 

 

相關文章