(Excerpt) Android data Adapter optimization: use efficient ViewHolder and androidviewholder
From: http://stackvoid.com/using-adapter-in-efficiency-way/
When using Listview or GridView, you often need a custom data adapter. Generally, getView () must be overwritten. In this method, there is a convertView parameter, this parameter is the View used to load data.
Simple but inefficient method for beginners
1 public View getView(int position, View convertView, ViewGroup parent) { 2 3 View item= inflater.inflate(R.layout.good_list_item, null, false); 4 5 ImageView img = (ImageView) item.findViewById(R.id.img); 6 TextView price = (TextView) item.findViewById(R.id.price); 7 img.setImageResource(R.drawable.ic_launcher); 8 price.setText("$"+list.get(position).price); 9 10 return item;11 }
Each time a view is loaded, many view objects need to be re-created. If a listview contains 10 thousand pieces of data, this loading method will stop.
Use convertView
Using the Recycler mechanism of Android and convertView to recycle the View, the efficiency is substantially improved. It is time-consuming to create a View. Therefore, the convertView passed in by the getview method should be fully utilized! = Null.
public View getView(int position, View convertView, ViewGroup parent) { 2 3 if(convertView==null){ 4 convertView = inflater.inflate(R.layout.good_list_item, null, false); 5 } 6 TextView tv_price = (TextView)convertView.findViewById(R.id.price) 7 ImageView iv = (ImageView)convertView.findViewByID(R.id.img); 8 9 return convertView;10 }
Use ViewHolder
ViewHolder encapsulates the view to be cached. The setTag of convertView caches the view for the next call. When the layout in your listview is diversified, the effect of viewholder is obvious, and the efficiency is improved again. The findViewById () method of View is also time-consuming. Therefore, you must consider calling it only once. Then you can use the View. getTag () method to obtain the ViewHolder object.
1 class ViewHolder {2 ImageView img; 3 TextView price; 4} 5 public View getView (int position, View convertView, ViewGroup parent) {6 ViewHolder holder = new ViewHolder (); 7 if (convertView = null) {8 convertView = inflater. inflate (R. layout. good_list_item, null, false); 9 holder. img = (ImageView) convertView. findViewById (R. id. img); 10 holder. price = (TextView) convertView. findViewById (R. id. price); 11 convertView. setTag (holder); 12} else {13 holder = (ViewHolder) convertView. getTag (); 14} 15 // set holder16 holder. img. setImageResource (R. drawable. ic_launcher); 17 holder. price. setText ("$" + list. get (position ). price); 18 19 return convertView; 20}
Elegant use of ViewHolder
When ViewHolder is used, the findViewById is repeated each time, and the View definition is added to the ViewHolder over and over again. If there are more views, isn't it annoying, the base-adapter-helper class library seems to solve this problem perfectly.
The design idea is to use SparseArray to store view references, instead of the original ViewHolder, without declaring a lot of views, which is concise and clear.
I also wrote a simple ViewHolder.
public class ViewHolder{ 2 3 private final SparseArray<View> views; 4 private View convertView; 5 6 private ViewHolder(View convertView){ 7 this.views = new SparseArray<View>(); 8 this.convertView = convertView; 9 convertView.setTag(this);10 }11 12 public static ViewHolder get(View convertView){13 if (convertView == null) {14 return new ViewHolder(convertView);15 }16 ViewHolder existedHolder = (ViewHolder) convertView.getTag();17 return existedHolder;18 }19 20 public <T extends View> T getView(int viewId) {21 View view = views.get(viewId);22 if (view == null) {23 view = convertView.findViewById(viewId);24 views.put(viewId, view);25 }26 return (T) view;27 }28 }
It is super simple and simple to use:
1 public View getView (int position, View convertView, ViewGroup parent) {2 if (convertView = null) {3 convertView = LayoutInflater. from (context) 4. inflate (R. layout. good_list_item, null, false); 5} 6 7 ViewHolder mViewHolder = ViewHolder. get (convertView); 8 TextView price = mViewHolder. getView (R. id. price); 9 //... other getView10 11 return convertView; 12}
In this case, do not use ViewHolder.