提升ListView的运行效率
之所以說ListView這個控件很難用,就是因為它有很多細節可以優化,其中運行效率就是很重要的一點。目前我們ListView的運行效率是很低的,因為在FruitAdapter的getView()方法中,每次都將布局重新加載了一遍,當ListView快速滾動的時候,這就會成為性能的瓶頸。
仔細觀察發現,getView()方法中還有一個convertView參數,這個參數用于將之前加載好的布局進行緩存,以便之后可以進行重用。修改FruitAdapter中的代碼,如下所示:
package com.example.administrator.activitydemo;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView;import java.util.List;public class FruitAdapter extends ArrayAdapter<Fruit> {private int resourceId;private List<Fruit> list;public FruitAdapter(Context context, int textViewResourceId, List<Fruit> list) {super(context, textViewResourceId, list);this.resourceId = textViewResourceId;this.list = list;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Fruit fruit = list.get(position);//獲取當前項的Fruit實例View view;if (convertView==null){view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);}else {view=convertView;}ImageView iv_name = (ImageView) view.findViewById(R.id.iv_name);//初始化圖片TextView tv_name = (TextView) view.findViewById(R.id.tv_name);//初始化文字iv_name.setImageResource(fruit.getImageId());//為ImageView設置圖片tv_name.setText("" + fruit.getName());//為TextView設置文字return view;} }可以看到,現在我們在getView()方法中進行了判斷,如果convertView為null,則使用LayoutInflater去加載布局,如果不為null,則直接對convertView進行重用。這樣就大大提高了ListView的運行效率,在快速滾動的時候也可以表現出更好的性能。
不過,目前我們的這份代碼還是可以繼續優化的,雖然現在已經不會再重復去加載布局,但是每次在getView()方法中還是會調用View的findViewById()方法來獲取一次控件的實例。我們可以借助一個ViewHolder來對這部分性能進行優化,修改FruitAdapter中的代碼,如下所示:
package com.example.administrator.activitydemo;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView;import java.util.List;public class FruitAdapter extends ArrayAdapter<Fruit> {private int resourceId;private List<Fruit> list;public FruitAdapter(Context context, int textViewResourceId, List<Fruit> list) {super(context, textViewResourceId, list);this.resourceId = textViewResourceId;this.list = list;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Fruit fruit = list.get(position);//獲取當前項的Fruit實例View view;ViewHolder viewHolder;if (convertView == null) {view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);viewHolder = new ViewHolder();viewHolder.iv_name = (ImageView) view.findViewById(R.id.iv_name);//初始化圖片viewHolder.tv_name = (TextView) view.findViewById(R.id.tv_name);//初始化文字view.setTag(viewHolder);//將ViewHolder存儲在View中} else {view = convertView;viewHolder = (ViewHolder) view.getTag();//重新獲取ViewHolder}viewHolder.iv_name.setImageResource(fruit.getImageId());//為ImageView設置圖片viewHolder.tv_name.setText("" + fruit.getName());//為TextView設置文字return view;}class ViewHolder {ImageView iv_name;TextView tv_name;} }我們新增了一個內部類ViewHolder,用于對控件的實例進行緩存。當covertView為null的時候,創建一個ViewHolder對象,并將控件的實例放在ViewHolder里,然后調用View的setTag()方法,將ViewHolder重新取出。這樣所有控件的實例都緩存在了ViewHolder里,就沒必要每次都通過findViewById()方法來獲取控件實例了。
通過這兩步優化之后,我們ListView的運行效率就已經非常不錯了。
效果圖:
?
總結
以上是生活随笔為你收集整理的提升ListView的运行效率的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 定制ListView的界面(使用自定义的
- 下一篇: 两个人的花呗可以互相还款吗