题接上文,对于普通场景BaseRecyclerAdapter已经满足需求了(也就是常见的单一类型条目,列表)。但是对于商城项目这种多布局多类型多数据业务是满足不了的。最近在写商城的首页,习惯于采用根据不同条目类型来加载不同布局,首先说说这种方式的弊端,1.代码多要写一堆getItemViewType,根据ItemViewType处理业务等一大堆代码。2.复用性差,由于很多类型,数据都在Adapter写死了,你没有办法拿给其他类似的业务场景使用。作为一名高(lan)效(duo)的程序员是恨不能容忍这样的事情的。那么有没有一种通用的Adapter每次拿来就可以用呢?
分析思路:我们知道适配器的思想就是把数据填充成View即 Data——>View
那么我们来做个假设: 假设有三种条目 1个人 3条狗 5只鸭
1个人————>一个美女Banner图
3条狗————>grid图
5只鸭————>list
对于一种类型一种布局模式,我相信我们能处理的得心应手了。那么我们可不可以把每一种类型拆分出来,在一个一个写,这不就是我们的强项了吗。最后我们把这些类型给管理起来组装到同一个RecylerView里面去,就像造车一样,冲压,上漆,发动机,最后由总装来装配这些东西构成一辆车。
我这里是借鉴MultiType-3.0来实现的。在此感谢https://github.com/drakeet/MultiType/wiki/Android-MultiType-3.0。我把MultiType的ItemViewBinder封装成BaseItemViewBinder使用起来更加简单便捷,并对外提供了接口以便响应点击事件。BaseItemViewBinder代码如下
package com.example.administrator.multitypelist.base;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.administrator.multitypelist.multitype.ItemViewBinder;
/**
- 创建时间:2018/2/9
- 创建人: liuzj
- 描述:基于MultiType-3x实现的多布局条目适配器 每一种类型继承本基类即可
- 包名:com.example.administrator.multitypelist.base
- 邮箱:[email protected]
*/
public abstract class BaseItemViewBinder
private int itemLayoutId;
private Context mContext;
private OnItemClickListener onItemClickListener;
private OnItemLongClickListener onItemLongClickListener;
public void setOnItemLongClickListener(OnItemLongClickListener onLongClickListener) {
this.onItemLongClickListener = onLongClickListener;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public BaseItemViewBinder(Context mContext, int itemLayoutId) {
this.mContext = mContext;
this.itemLayoutId = itemLayoutId;
}
@NonNull
@Override
protected BaseViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
View view = inflater.inflate(itemLayoutId, parent, false);
return new BaseViewHolder(mContext, view);
}
@Override
protected void onBindViewHolder(@NonNull BaseViewHolder holder, @NonNull final T data) {
convert(holder, data);
if (onItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemClickListener.onItemClick(data);
}
});
}
if (onItemLongClickListener != null) {
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
onItemLongClickListener.onLongItemClick(data);
return true;
}
});
}
}
protected abstract void convert(BaseViewHolder holder, T data);
/*接口回调点击和长按事件*/
public interface OnItemClickListener {
void onItemClick(T bean);
}
public interface OnItemLongClickListener {
void onLongItemClick(T bean);
}
}
示例Demo
package com.example.administrator.multitypelist;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import com.example.administrator.multitypelist.base.BaseItemViewBinder;
import com.example.administrator.multitypelist.bean.BannerBean;
import com.example.administrator.multitypelist.bean.ListBean;
import com.example.administrator.multitypelist.bean.TitleBean;
import com.example.administrator.multitypelist.bind.BannerViewBind;
import com.example.administrator.multitypelist.bind.ListViewBind;
import com.example.administrator.multitypelist.bind.TitleViewBind;
import com.example.administrator.multitypelist.multitype.Items;
import com.example.administrator.multitypelist.multitype.MultiTypeAdapter;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private Items items;
private MultiTypeAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
final GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
GridLayoutManager.SpanSizeLookup spanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
Object item = items.get(position);
return (item instanceof BannerBean || item instanceof TitleBean) ? 2 : 1;
}
};
layoutManager.setSpanSizeLookup(spanSizeLookup);
recyclerView.setLayoutManager(layoutManager);
int space = getResources().getDimensionPixelSize(R.dimen.normal_space);
recyclerView.addItemDecoration(new PostItemDecoration(space, spanSizeLookup));
adapter = new MultiTypeAdapter();
BannerViewBind bannerViewBind = new BannerViewBind(this, R.layout.item_banner);
TitleViewBind titleViewBind = new TitleViewBind(this, R.layout.item_title);
titleViewBind.setOnItemClickListener(new BaseItemViewBinder.OnItemClickListener() {
@Override
public void onItemClick(TitleBean bean) {
Toast.makeText(MainActivity.this, "你点的是" + bean.getTitle(), Toast.LENGTH_SHORT).show();
}
});
ListViewBind listViewBind = new ListViewBind(this, R.layout.item_list);
listViewBind.setOnItemClickListener(new BaseItemViewBinder.OnItemClickListener() {
@Override
public void onItemClick(ListBean bean) {
Toast.makeText(MainActivity.this, "你点的是" + bean.getDetail(), Toast.LENGTH_SHORT).show();
}
});
adapter.register(BannerBean.class, bannerViewBind);
adapter.register(TitleBean.class, titleViewBind);
adapter.register(ListBean.class, listViewBind);
recyclerView.setAdapter(adapter);
items = new Items();
loadBannerData();
}
private void loadListData() {
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
items.add(new ListBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1518157976664&di=d93bcf68dcaee2420b37b7cf9d5f4921&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2Fdbb44aed2e738bd41f16dd0daa8b87d6277ff9d3.jpg",
"1号美女"));
items.add(new ListBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1518157976663&di=16a4c61d68fd55e83552d0b9737239c2&imgtype=0&src=http%3A%2F%2Fimage.tianjimedia.com%2FuploadImages%2F2015%2F187%2F56%2F3N637PII75MH.jpg",
"2号美女"));
items.add(new ListBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1518157976661&di=08570def3828bda48035585a6b2651a0&imgtype=0&src=http%3A%2F%2Fwww.hinews.cn%2Fpic%2F0%2F10%2F05%2F65%2F10056539_779433.jpg",
"3号美女"));
items.add(new ListBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1518157976660&di=6dfe0259f1b0cba6dda33a844f3b6c50&imgtype=0&src=http%3A%2F%2Fimg5.xiazaizhijia.com%2Fwalls%2F20160108%2F1024x768_d33e81709cb5f3b.jpg",
"4号美女"));
adapter.setItems(items);
adapter.notifyDataSetChanged();
}
}, 500);
}
private void loadTitleData() {
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
items.add(new TitleBean("美女写真"));
adapter.setItems(items);
adapter.notifyDataSetChanged();
loadListData();
}
}, 300);
}
private void loadBannerData() {
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
ArrayList banners = new ArrayList<>();
banners.add("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3878847766,3988120331&fm=200&gp=0.jpg");
banners.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1518157976665&di=88c7d013f9009cdf4eabc8e2aadae134&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimage%2Fc0%253Dshijue1%252C0%252C0%252C294%252C40%2Fsign%3D72e134ec88025aafc73f76889384c111%2Fa50f4bfbfbedab64a0bd3fecfd36afc378311eca.jpg");
banners.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1518157976665&di=88c7d013f9009cdf4eabc8e2aadae134&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimage%2Fc0%253Dshijue1%252C0%252C0%252C294%252C40%2Fsign%3D72e134ec88025aafc73f76889384c111%2Fa50f4bfbfbedab64a0bd3fecfd36afc378311eca.jpg");
banners.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1518157976665&di=88c7d013f9009cdf4eabc8e2aadae134&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimage%2Fc0%253Dshijue1%252C0%252C0%252C294%252C40%2Fsign%3D72e134ec88025aafc73f76889384c111%2Fa50f4bfbfbedab64a0bd3fecfd36afc378311eca.jpg");
items.add(new BannerBean(banners));
adapter.setItems(items);
adapter.notifyDataSetChanged();
loadTitleData();
}
}, 900);
}
}
其中bannerViewBind,titleViewBind,listViewBind均是继承BaseItemViewBinder实现
是不是很简单!轻轻松松搞定RecyclerView多布局。