Android BaseAdapter multi-layout Cache
ListView is one of the most common controls in App development. It is followed by the use of BaseAdapter, and the role of BaseAdapter is to provide data sources for our ListView, I believe everyone will use the general usage. Today we will mainly explain how to efficiently load ItemView with multiple styles in the list.
Let's take a look at it first:
: There are two types of ItemView in the entire list. When the traditional ConvertView is used to cache subitems, it is found that the two la s are out of order as soon as they slide. Later, for the project progress, if no memory overflow occurs, ConvertView is not used as the sub-View cache. Today, when I look at the source code of the Adapter and its sub-classes, I find the following code, I instantly thought that there was no problem with multi-layout and multi-cache, so I checked it online and used these methods to implement it. The Code is as follows:
Public interface Adapter {void registerDataSetObserver (DataSetObserver observer); void unregisterDataSetObserver (DataSetObserver observer); int getCount (); Object getItem (int position); long getItemId (int position ); boolean hasStableIds (); View getView (int position, View convertView, ViewGroup parent); static final int IGNORE_ITEM_VIEW_TYPE = AdapterView. ITEM_VIEW_TYPE_IGNORE; int getItemViewType (int position); // method 1, obtain the layout type int getViewTypeCount (); // method 2, and obtain the total layout static final int NO_SELECTION = Integer. MIN_VALUE;/*** @ return true if this adapter doesn't contain any data. this is used to determine * whether the empty view shoshould be displayed. A typical implementation will return * getCount () = 0 but since getCount () between des the headers and footers, specialized * adapters might want a different behavior. */boolean isEmpty ();}
It is the two methods marked in red, and BaseAdapter has provided us with the default implementation, so that we do not pay attention to these two methods. The default Implementation of BaseAdapter is as follows:
package android.widget;import android.database.DataSetObservable;import android.database.DataSetObserver;import android.view.View;import android.view.ViewGroup;public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter { private final DataSetObservable mDataSetObservable = new DataSetObservable(); public boolean hasStableIds() { return false; } public void registerDataSetObserver(DataSetObserver observer) { mDataSetObservable.registerObserver(observer); } public void unregisterDataSetObserver(DataSetObserver observer) { mDataSetObservable.unregisterObserver(observer); } public void notifyDataSetChanged() { mDataSetObservable.notifyChanged(); } public void notifyDataSetInvalidated() { mDataSetObservable.notifyInvalidated(); } public boolean areAllItemsEnabled() { return true; } public boolean isEnabled(int position) { return true; } public View getDropDownView(int position, View convertView, ViewGroup parent) { return getView(position, convertView, parent); } public int getItemViewType(int position) { return 0; } public int getViewTypeCount() { return 1; } public boolean isEmpty() { return getCount() == 0; }}
With these two methods, we only need to rewrite these two methods. below is the Adapter code I have rewritten:
/*************************************** * ******************** @ File Name: countryListAdapter. java * @ file Author: rzq * @ Creation Time: 2:33:43, January 1, July 22, 2014 * @ file Description: country list adapter * @ modification history: create the initial version ************************************** on April 9, July 22, 2014 ************************************ * ********************/public class CountryListAdapter extends BaseAdapter {private Context mContext; private ArrayList
DataList; private Country country; private ViewHolder holder1; private ViewHolder holder2; public CountryListAdapter (Context context, ArrayList
DataList) {this. mContext = context; this. dataList = dataList;} @ Overridepublic int getCount () {return dataList. size () ;}@ Overridepublic Object getItem (int position) {return dataList. get (position) ;}@ Overridepublic long getItemId (int position) {return 0 ;}@ Overridepublic View getView (int position, View convertView, ViewGroup parent) {country = (Country) dataList. get (position); int type = getItemViewType (position); if (convertView = null) {switch (type) {case 0: holder1 = new ViewHolder (); convertView = LayoutInflater. from (mContext ). inflate (R. layout. catagories_expandlistview_group, parent, false); holder1.textView = (TextView) convertView. findViewById (R. id. catagories_group_textview); convertView. setTag (holder1); break; case 1: holder2 = new ViewHolder (); convertView = LayoutInflater. from (mContext ). inflate (R. layout. register_expandlistview_child, parent, false); holder2.textView = (TextView) convertView. findViewById (R. id. register_child_textview); holder2.imageView = (ImageView) convertView. findViewById (R. id. register_country_flag); convertView. setTag (holder2); break;} else {switch (type) {case 0: holder1 = (ViewHolder) convertView. getTag (); break; case 1: holder2 = (ViewHolder) convertView. getTag (); break ;}} switch (type) {case 0: holder1.textView. setText (country. getIndexChar (); break; case 1: holder2.textView. setText (country. getCountryName (); holder2.imageView. setImageDrawable (country. getFlagDrawable (); break;} return convertView;} @ Overridepublic int getItemViewType (int position) {country = (Country) getItem (position); if (country. isGroup () {return 0;} else {return 1 ;}@ Overridepublic int getViewTypeCount () {return 2;} private static class ViewHolder {private TextView textView; private ImageView imageView ;}}
This ensures that the memory does not overflow and improves the loading efficiency of ListView.