RecyclerView 能夠用ViewType來區分不一樣的item,也能夠知足需求,但仍是存在一些問題,好比:php
一般寫一個多Item列表的方法git
主要操做步驟github
代碼以下所示面試
public class HomePageAdapter extends RecyclerView.Adapter { public static final int TYPE_BANNER = 0; public static final int TYPE_AD = 1; public static final int TYPE_TEXT = 2; public static final int TYPE_IMAGE = 3; public static final int TYPE_NEW = 4; private List<HomePageEntry> mData; public void setData(List<HomePageEntry> data) { mData = data; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType){ case TYPE_BANNER: return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_banner_layout,null)); case TYPE_AD: return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_ad_item_layout,null)); case TYPE_TEXT: return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_text_item_layout,null)); case TYPE_IMAGE: return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_image_item_layout,null)); case TYPE_NEW: return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_news_item_layout,null)); } return null; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int type = getItemViewType(position); switch (type){ case TYPE_BANNER: // banner 邏輯處理 break; case TYPE_AD: // 廣告邏輯處理 break; case TYPE_TEXT: // 文本邏輯處理 break; case TYPE_IMAGE: //圖片邏輯處理 break; case TYPE_NEW: //視頻邏輯處理 break; // ... 此處省去N行代碼 } } @Override public int getItemViewType(int position) { if(position == 0){ return TYPE_BANNER;//banner在開頭 }else { return mData.get(position).type;//type 的值爲TYPE_AD,TYPE_IMAGE,TYPE_AD,等其中一個 } } @Override public int getItemCount() { return mData == null ? 0:mData.size(); } public static class BannerViewHolder extends RecyclerView.ViewHolder{ public BannerViewHolder(View itemView) { super(itemView); //綁定控件 } } public static class NewViewHolder extends RecyclerView.ViewHolder{ public VideoViewHolder(View itemView) { super(itemView); //綁定控件 } } public static class AdViewHolder extends RecyclerView.ViewHolder{ public AdViewHolder(View itemView) { super(itemView); //綁定控件 } } public static class TextViewHolder extends RecyclerView.ViewHolder{ public TextViewHolder(View itemView) { super(itemView); //綁定控件 } } public static class ImageViewHolder extends RecyclerView.ViewHolder{ public ImageViewHolder(View itemView) { super(itemView); //綁定控件 } } }
上面那樣寫的弊端segmentfault
核心目的就是三個服務器
在getItemViewType方法中。markdown
private ArrayList<InterItemView> headers = new ArrayList<>(); public interface InterItemView { /** * 建立view * @param parent parent * @return view */ View onCreateView(ViewGroup parent); /** * 綁定view * @param headerView headerView */ void onBindView(View headerView); } /** * 獲取類型,主要做用是用來獲取當前項Item(position參數)是哪一種類型的佈局 * @param position 索引 * @return int */ @Deprecated @Override public final int getItemViewType(int position) { if (headers.size()!=0){ if (position<headers.size()) { return headers.get(position).hashCode(); } } if (footers.size()!=0){ int i = position - headers.size() - mObjects.size(); if (i >= 0){ return footers.get(i).hashCode(); } } return getViewType(position-headers.size()); }
onCreateViewHolderide
/** * 建立viewHolder,主要做用是建立Item視圖,並返回相應的ViewHolder * @param parent parent * @param viewType type類型 * @return 返回viewHolder */ @NonNull @Override public final BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = createViewByType(parent, viewType); if (view!=null){ return new BaseViewHolder(view); } final BaseViewHolder viewHolder = OnCreateViewHolder(parent, viewType); setOnClickListener(viewHolder); return viewHolder; } private View createViewByType(ViewGroup parent, int viewType){ for (InterItemView headerView : headers){ if (headerView.hashCode() == viewType){ View view = headerView.onCreateView(parent); StaggeredGridLayoutManager.LayoutParams layoutParams; if (view.getLayoutParams()!=null) { layoutParams = new StaggeredGridLayoutManager.LayoutParams(view.getLayoutParams()); } else { layoutParams = new StaggeredGridLayoutManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } layoutParams.setFullSpan(true); view.setLayoutParams(layoutParams); return view; } } for (InterItemView footerView : footers){ if (footerView.hashCode() == viewType){ View view = footerView.onCreateView(parent); StaggeredGridLayoutManager.LayoutParams layoutParams; if (view.getLayoutParams()!=null) { layoutParams = new StaggeredGridLayoutManager.LayoutParams(view.getLayoutParams()); } else { layoutParams = new StaggeredGridLayoutManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } layoutParams.setFullSpan(true); view.setLayoutParams(layoutParams); return view; } } return null; }
在onBindViewHolder方法中。能夠看到,在此方法中,添加一種header類型的view,則經過onBindView進行數據綁定。佈局
/** * 綁定viewHolder,主要做用是綁定數據到正確的Item視圖上。當視圖從不可見到可見的時候,會調用這個方法。 * @param holder holder
*/ @Override public final void onBindViewHolder(BaseViewHolder holder, int position) { holder.itemView.setId(position); if (headers.size()!=0 && position<headers.size()){ headers.get(position).onBindView(holder.itemView); return ; } int i = position - headers.size() - mObjects.size(); if (footers.size()!=0 && i>=0){ footers.get(i).onBindView(holder.itemView); return ; } OnBindViewHolder(holder,position-headers.size()); } ```
如何使用,以下所示,這個就是banner類型,能夠說是解耦了以前adapter中複雜的操做學習
InterItemView interItemView = new InterItemView() { @Override public View onCreateView(ViewGroup parent) { BannerView header = new BannerView(HeaderFooterActivity.this); header.setHintView(new ColorPointHintView(HeaderFooterActivity.this, Color.YELLOW, Color.GRAY)); header.setHintPadding(0, 0, 0, (int) AppUtils.convertDpToPixel( 8, HeaderFooterActivity.this)); header.setPlayDelay(2000); header.setLayoutParams(new RecyclerView.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, (int) AppUtils.convertDpToPixel(200, HeaderFooterActivity.this))); header.setAdapter(new BannerAdapter(HeaderFooterActivity.this)); return header; } @Override public void onBindView(View headerView) { } }; adapter.addHeader(interItemView);
封裝後好處