本文為菜鳥窩作者蔣志碧的連載岳悟。“從 0 開始開發(fā)一款直播 APP ”系列來聊聊時下最火的直播 APP派桩,如何完整的實現(xiàn)一個類"騰訊直播"的商業(yè)化項目
視頻地址:http://www.cniao5.com/course/10121
【從 0 開始開發(fā)一款直播 APP】3.1 高層封裝之 Adapter — ListView & GridView
【從 0 開始開發(fā)一款直播 APP】3.2 高層封裝之 Adapter — RecyclerView 實現(xiàn)單布局展示
【從 0 開始開發(fā)一款直播 APP】3.3 高層封裝之 Adapter -- RecyclerView 實現(xiàn)多條目展示
【從 0 開始開發(fā)一款直播 APP】3.4 高層封裝之 Adapter -- RecyclerView 優(yōu)雅的添加 Header构诚、Footer
一、多條目 Adapter 封裝實現(xiàn)聊天界面
上章已經(jīng)講解了 RecyclerView 的基本封裝铆惑,這次對于多條目展示進(jìn)行講解范嘱,效果如下:
RecyclerView.Adapter 的 getItemViewType(int position) 這個方法送膳,可以根據(jù)當(dāng)前位置獲取一個 viewType 最終會傳到 onCreateViewHolder() 這個方法中, 通過一個標(biāo)識來判斷條目的布局丑蛤。
1.1叠聋、定義一個接口,用來獲取布局
public interface MutipleTypeSupport<T> {
//根據(jù)當(dāng)前條目獲取布局
int getLayoutId(T t);
}
1.2受裹、在原來的Adapter基礎(chǔ)上做修改碌补,將MutipleTypeSupport接口傳入,讓用戶傳遞布局類型
private MutipleTypeSupport<T> mMutipleTypeSupport;
public RecyclerViewAdapter(Context context,List<T> datas,MutipleTypeSupport typeSupport){
this(context,-1,datas);
this.mMutipleTypeSupport = typeSupport;
}
1.3棉饶、根據(jù) getItemViewType 獲取當(dāng)前位置的 item 類型厦章, position 就是當(dāng)前 item 的值
//調(diào)用 onCreateViewHolder() 方法之前調(diào)用 getItemViewType()
@Override
public int getItemViewType(int position) {
if (mMutipleTypeSupport != null){
return mMutipleTypeSupport.getLayoutId(mDatas.get(position));
}
return super.getItemViewType(position);
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//判斷是否需要多布局
if (mMutipleTypeSupport != null){
mLayoutId = viewType;
}
View itemView = mInflater.inflate(mLayoutId,parent,false);
return new RecyclerViewHolder(itemView);
}
1.4、其它方法不變照藻,所有代碼
public abstract class RecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerViewHolder> {
protected int mLayoutId;
protected List<T> mDatas;
protected Context mContext;
private LayoutInflater mInflater;
private MutipleTypeSupport<T> mMutipleTypeSupport;
public RecyclerViewAdapter(Context context,List<T> datas,MutipleTypeSupport typeSupport){
this(context,-1,datas);
this.mMutipleTypeSupport = typeSupport;
}
public RecyclerViewAdapter(Context context, int layoutId, List<T> datas) {
this.mContext = context;
this.mLayoutId = layoutId;
this.mDatas = datas;
this.mInflater = LayoutInflater.from(mContext);
}
//調(diào)用onCreateViewHolder方法之前調(diào)用getItemViewType
@Override
public int getItemViewType(int position) {
//如果支持多布局袜啃,返回所有布局
if (mMutipleTypeSupport != null){
return mMutipleTypeSupport.getLayoutId(mDatas.get(position));
}
return super.getItemViewType(position);
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//多布局支持
if (mMutipleTypeSupport != null){
mLayoutId = viewType;
}
View itemView = mInflater.inflate(mLayoutId,parent,false);
return new RecyclerViewHolder(itemView);
}
@Override
public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
//ViewHolder優(yōu)化
bindData(holder,mDatas.get(position),position);
}
/**
* 把必要參數(shù)傳進(jìn)去
* @param holder RecyclerViewHolder
* @param t 數(shù)據(jù)
* @param position 當(dāng)前位置
*/
protected abstract void bindData(RecyclerViewHolder holder, T t,int position);
@Override
public int getItemCount() {
return mDatas.size();
}
}
封裝完就寫的 Demo 看看效果吧。
二幸缕、多布局 Demo 實現(xiàn)
2.1群发、 MutipleAdapter 繼承 RecyclerViewAdapter ,通過 getLayoutId() 傳遞布局
public class MutipleAdaper extends RecyclerViewAdapter<Item> {
public MutipleAdaper(Context context, List<Item> datas) {
super(context, datas, new MutipleTypeSupport<Item>() {
@Override
public int getLayoutId(Item item) {
if (item.getType() == 1){//該處1是通過 item 傳過來的
return R.layout.list_item;
}else {
return R.layout.list_item1;
}
}
});
}
@Override
protected void bindData(RecyclerViewHolder holder, final Item item, int position) {
holder.setText(R.id.tv1,item.getTv1())
.setImageResource(R.id.img,item.getRes())
.setOnClickListener(R.id.tv1, new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,item.getTv1(),Toast.LENGTH_SHORT).show();
}
});
}
}
**2.2发乔、 AdapterActivity **
public class AdapterActivity extends BaseActivity {
private MutipleAdaper mMutipleAdaper;
private RecyclerView mRecyclerView;
@Override
protected void setToolbar() {
}
@Override
protected void setListener() {
}
//填充數(shù)據(jù)
@Override
protected void initData() {
Datas = new ArrayList<>();
for (int i = 1; i <= 30; i++) {
if (i % 2 == 0) {
Datas.add(new Item(R.drawable.tab_publish_normal,"我 get 新技能 " + i,0));//根據(jù) Item 類 最后一個參數(shù)確定填充數(shù)據(jù)的不同
}else {
Datas.add(new Item(R.drawable.tab_publish_normal,"你 get 新技能 " + i,1));
}
}
mMutipleAdaper = new MutipleAdaper(this,Datas);
mRecyclerView.setAdapter(mMutipleAdaper);
}
@Override
protected void initView() {
mRecyclerView = obtainView(R.id.recyclerView);
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
}
@Override
protected int getLayoutId() {
return R.layout.activity_adapter;
}
}
2.3熟妓、 Item 類
public class Item {
private int res;//圖片
private String tv1;//文字
private int type;//類型
public Item(int res, String tv1,int type) {
this.res = res;
this.tv1 = tv1;
this.type = type;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getRes() {
return res;
}
public void setRes(int res) {
this.res = res;
}
public String getTv1() {
return tv1;
}
public void setTv1(String tv1) {
this.tv1 = tv1;
}
}
對于RecyclerView 實現(xiàn)多布局講解完畢,下一章繼續(xù)為大家講解 RecyclerView 封裝之優(yōu)雅添加 Header列疗、Footer滑蚯。
總結(jié)
多條目的封裝
1、在單條目基礎(chǔ)上通過構(gòu)造函數(shù)傳遞一個提供布局的接口抵栈,通過 ViewType 類型判斷到底使用什么布局。
2坤次、在 getItemViewType() 方法中判斷布局類型古劲,在 onCreateViewHolder() 方法中判斷是否需要多布局,根據(jù)用戶需要實現(xiàn)不同的構(gòu)造函數(shù)