List Implementation of multiple android la S and android la s
Recently, there is a list effect that requires a list with multiple la S. The final result is as follows:
I also asked my colleagues and friends in the Development Group, but they didn't get the optimal implementation method. It seems that there are still few requirements for this complex list, I also made some detours and sorted out some of my implementation methods. I hope it will be helpful to some friends who do not know about it.
Implementation Method 1: (re-inflate itemView upon getView, convertView is not reused, performance is low, and running is OK)
Private class MyAdapter extends BaseAdapter {private List <Object> datas = Collections. EMPTY_LIST; public void setDatas (List <Object> datas) {if (datas = null) {datas = Collections. EMPTY_LIST;} this. datas = datas; notifyDataSetChanged () ;}@ Override public int getCount () {return datas. size () ;}@ Override public Object getItem (int position) {return datas. get (position) ;}@ Override public long getI TemId (int position) {return 0 ;}@ Override public View getView (int position, View convertView, ViewGroup parent) {Object data = getItem (position); if (data instanceof Folder) {FolderViewHolder holder = null; if (convertView! = Null & convertView. getTag () instanceof FolderViewHolder) {// consistent View and Data Type holder = (FolderViewHolder) convertView. getTag ();} else {convertView = mInflater. inflate (R. layout. listitem1, null); holder = new FolderViewHolder (convertView); convertView. setTag (holder);} holder. setData (Folder) data);} else {FileViewHolder holder = null; if (convertView! = Null & convertView. getTag () instanceof FileViewHolder) {// View consistent with the data type holder = (FileViewHolder) convertView. getTag ();} else {convertView = mInflater. inflate (R. layout. listitem2, null); holder = new FileViewHolder (convertView); convertView. setTag (holder);} holder. setData (File) data);} return convertView;} private class FolderViewHolder {public TextView tvName; public FolderViewHolder (View itemView) {tvName = (TextView) itemView. findViewById (R. id. tvName);} public void setData (Folder data) {tvName. setText (data. name) ;}} private class FileViewHolder {public TextView tvName; public FileViewHolder (View itemView) {tvName = (TextView) itemView. findViewById (R. id. tvName);} public void setData (File data) {tvName. setText (data. name );}}
Implementation Method 2: (because method 1 constantly inflate the view, which affects the performance, consider whether to reuse the view that has been inflate as much as possible, and then add a cache, however, an exception is displayed when the data is quickly slide or switched in the actual test. The reason should be the reason why AbsListView # RecycleBin is cached. I will clarify the cause and then add it, looking at other people's code is the most painful ...)
Private class MyAdapter extends BaseAdapter {private List <View> folderViewCaches = new ArrayList <View> (5); private List <View> fileViewCaches = new ArrayList <View> (5 ); private List <Object> datas = Collections. EMPTY_LIST; public void setDatas (List <Object> datas) {if (datas = null) {datas = Collections. EMPTY_LIST;} this. datas = datas; notifyDataSetChanged () ;}@ Override public int getCount () {retur N datas. size () ;}@ Override public Object getItem (int position) {return datas. get (position) ;}@ Override public long getItemId (int position) {return 0 ;}@ Override public View getView (int position, View convertView, ViewGroup parent) {Object data = getItem (position); if (data instanceof Folder) {// Folder, R. layout. view FolderViewHolder holder = null for listitem1; if (convertView! = Null & convertView. getTag () instanceof FolderViewHolder) {// consistent View and Data Type holder = (FolderViewHolder) convertView. getTag ();} else {if (convertView! = Null) {// cached to the file list fileViewCaches. add (convertView); convertView = null;} // obtain the cache that has been removed from the ListView from the cache (comment out this part of the code and it will be normal) if (! FolderViewCaches. isEmpty () {for (View cache: folderViewCaches) {if (cache. getParent () = null) {// The cached View has been removed from the listView convertView = cache; holder = (FolderViewHolder) convertView. getTag (); folderViewCaches. remove (cache); break ;}}// still not, re-inflate if (convertView = null) {convertView = mInflater. inflate (R. layout. listitem1, null); holder = new FolderViewHolder (convertView); convertView. setTag (h Older) ;}} holder. setData (Folder) data);} else {// file, which should return R. layout. view FileViewHolder holder = null for listitem2; if (convertView! = Null & convertView. getTag () instanceof FileViewHolder) {// View and Data Type consistent holder = (FileViewHolder) convertView. getTag ();} else {if (convertView! = Null) {// cache to the folder list folderViewCaches. add (convertView); convertView = null;} // obtain the cache that has been removed from the ListView from the cache (comment out this part of the code and it will be normal) if (! FileViewCaches. isEmpty () {for (View cache: fileViewCaches) {if (cache. getParent () = null) {// The cached View has been removed from the listView convertView = cache; holder = (FileViewHolder) convertView. getTag (); fileViewCaches. remove (cache); break ;}}// still not, re-inflate if (convertView = null) {convertView = mInflater. inflate (R. layout. listitem2, null); holder = new FileViewHolder (convertView); convertView. setTag (holder) ;}} holder. setData (File) data);} return convertView ;}}
Method 3:(Optimal Implementation and normal operation)
After carefully reading the source code of ListView, we found that the Adapter itself supports different la S, and AbsListView # RecycleBin also supports cache policies for different types of la S, RecycleBin. mViewTypeCount indicates the number of View types.
We need to rewrite the following three methods of the Adapter:
1. getViewTypeCount:
/*** Number of views with different la S */@ Override public int getViewTypeCount () {return 2 ;}
2. getItemViewType
/*** View type corresponding to the corresponding position */@ Override public int getItemViewType (int position) {if (getItem (position) instanceof Folder) {return TYPE_FOLDER ;} else {return TYPE_FILE ;}}
3. getView: returns a view of the corresponding position type by determining the type of position:
@ Override public View getView (int position, View convertView, ViewGroup parent) {Object data = getItem (position); if (data instanceof Folder) {// TYPE_FOLDER, Folder, r. layout. view FolderViewHolder holder = null for listitem1; if (convertView! = Null) {holder = (FolderViewHolder) convertView. getTag ();} else {convertView = mInflater. inflate (R. layout. listitem1, null); holder = new FolderViewHolder (convertView); convertView. setTag (holder);} holder. setData (Folder) data);} else {// TYPE_FILE, file, should return R. layout. view FileViewHolder holder = null for listitem2; if (convertView! = Null) {holder = (FileViewHolder) convertView. getTag ();} else {convertView = mInflater. inflate (R. layout. listitem2, null); holder = new FileViewHolder (convertView); convertView. setTag (holder);} holder. setData (File) data);} return convertView ;}
Github Source Code address of this demo:
Https://github.com/John-Chen/BlogSamples/tree/master/MultipleListTest
Apk:
Https://github.com/John-Chen/BlogSamples/blob/master/MultipleListTest/MultipleListTest.apk
If you have any questions, please kindly advise!