- 核心目的就是三個
- 避免類的類型檢查與類型轉型
- 加強Adapter的擴展性
- 加強Adapter的可維護性
- 當列表中類型增長或減小時Adapter中主要改動的就是getItemViewType、onCreateViewHolder、onBindViewHolder這三個方法,所以,咱們就從這三個方法中開始着手。
- 既然可能存在多個type類型的view,那麼能不能把這些好比banner,廣告,文本,視頻,新聞等當作一個HeaderView來操做。
- 在getItemViewType方法中。
- 減小if之類的邏輯判斷簡化代碼,能夠簡單粗暴的用hashCode做爲增長type標識。
- 經過建立列表的佈局類型,同時返回的再也不是簡單的佈局類型標識,而是佈局的hashCode值
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());
}
- onCreateViewHolder
- getItemViewType返回的是佈局hashCode值,也就是onCreateViewHolder(ViewGroup parent, int viewType)參數中的viewType
/**
* 建立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
* @param position 索引
*/
@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);
- 封裝後好處
- 拓展性——Adapter並不關心不一樣的列表類型在列表中的位置,所以對於Adapter來講列表類型能夠隨意增長或減小。十分方便,同時設置類型view的佈局和數據綁定都不須要在adapter中處理。充分解耦。
- 可維護性——不一樣的列表類型由adapter添加headerView處理,哪怕添加多個headerView,相互之間互不干擾,代碼簡潔,維護成本低。