ANDROID多種布局的列表實現

來源:互聯網
上載者:User

ANDROID多種布局的列表實現
 這個我也問了同事以及開發群裡的朋友,居然都沒得到最優的實現方式的回答,看來這種複雜列表的需求還是比較少的,我自己也走了一些彎路,把我幾個實現的方式整理下,希望對於還不瞭解的朋友有所協助。   實現方式1:(每次getView時重新inflate itemView,convertView沒有複用,效能低,運行沒問題)  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 getItemId(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){                    //View與資料類型一致                    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與資料類型一致                    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);        }    }   實現方式2:(因為方式1不斷inflate view,影響效能,於是考慮是否能儘可能重用已經inflate的view,於是添加了一個緩衝,不過實際測試快速滑動或切換資料會顯示異常,應該是AbsListView#RecycleBin緩衝的原因,具體原因我後面理清了再添加,看別人的代碼最痛苦了。。。)  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() {            return 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){                //檔案夾,應該返回R.layout.listitem1對應的View                FolderViewHolder holder = null;                if(convertView != null && convertView.getTag() instanceof FolderViewHolder){                    //View與資料類型一致                    holder = (FolderViewHolder) convertView.getTag();                }else{                    if(convertView != null){                        //緩衝到檔案清單                        fileViewCaches.add(convertView);                        convertView = null;                    }                     //從緩衝裡面取已從ListView移除的緩衝(注釋掉此部分代碼顯示正常)                    if(!folderViewCaches.isEmpty()){                        for(View cache : folderViewCaches){                            if(cache.getParent() == null){                                //緩衝的View已從listView裡面移除                                convertView = cache;                                holder = (FolderViewHolder) convertView.getTag();                                folderViewCaches.remove(cache);                                break;                            }                        }                    }                     //還是沒有,重新inflate                    if(convertView == null){                        convertView = mInflater.inflate(R.layout.listitem1, null);                        holder = new FolderViewHolder(convertView);                        convertView.setTag(holder);                    }                }                 holder.setData((Folder) data);             }else{                //檔案,應該返回R.layout.listitem2對應的View                FileViewHolder holder = null;                if(convertView != null && convertView.getTag() instanceof FileViewHolder){                    //View與資料類型一致                    holder = (FileViewHolder) convertView.getTag();                }else{                    if(convertView != null){                        //緩衝到資料夾清單                        folderViewCaches.add(convertView);                        convertView = null;                    }                     //從緩衝裡面取已從ListView移除的緩衝(注釋掉此部分代碼顯示正常)                    if(!fileViewCaches.isEmpty()){                        for(View cache : fileViewCaches){                            if(cache.getParent() == null){                                //緩衝的View已從listView裡面移除                                convertView = cache;                                holder = (FileViewHolder) convertView.getTag();                                fileViewCaches.remove(cache);                                break;                            }                        }                    }                     //還是沒有,重新inflate                    if(convertView == null){                        convertView = mInflater.inflate(R.layout.listitem2, null);                        holder = new FileViewHolder(convertView);                        convertView.setTag(holder);                    }                }                 holder.setData((File) data);            }             return convertView;        }    }  實現方式3:(最佳實現,運行正常) 後面仔細閱讀ListView相關源碼,才發現Adapter本身就支援不同的布局了,而且AbsListView#RecycleBin也支援不同類型的布局的緩衝策略,RecycleBin.mViewTypeCount標示有多少種View類型。 我們需要做的就是重寫Adapter的下面3個方法: 1.getViewTypeCount:       /**         * 有多少種不同布局的View         */        @Override        public int getViewTypeCount() {            return 2;        }   2.getItemViewType          /**         * 相應position對應的View類型         */        @Override        public int getItemViewType(int position) {            if(getItem(position) instanceof Folder){                return TYPE_FOLDER;            }else{                return TYPE_FILE;            }        }       3.getView,通過判斷對應position的類型,返回相應類型的view:       @Override        public View getView(int position, View convertView, ViewGroup parent) {            Object data = getItem(position);             if(data instanceof Folder){                //TYPE_FOLDER,檔案夾,應該返回R.layout.listitem1對應的View                FolderViewHolder holder = null;                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,檔案,應該返回R.layout.listitem2對應的View                FileViewHolder holder = null;                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;        } 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.