- 核心目的就是三个
- 避免类的类型检查与类型转型
- 加强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,相互之间互不干扰,代码简洁,维护成本低。