android adapter的性能小结
一般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不会太多,内存的消耗能够在我的容忍范围之内,才可以这样做。