今天開始講RecycleView的系列教程。分割線,分組,局部刷新,動(dòng)態(tài)添加,緩存原理,抖音效果,瀑布流。嵌套,動(dòng)畫等等
第三方萬能適配器:
? ? ? ? ? ? compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22'
本文就是模仿這個(gè),看了源碼,一步一步寫的
支持多類型
支持下拉和上拉更多
支持動(dòng)態(tài)添加和刪除
支持頭部
支持點(diǎn)擊事件
支持動(dòng)畫
使用超簡單
背景
1.重復(fù)寫4個(gè)方法和綁定過程,hold等,代碼太多了
2.需要自己寫點(diǎn)擊事件的監(jiān)聽
3.沒有使用adapter之前,使用萬能adapter之后,代碼少了不少!
數(shù)據(jù)怎么辦?布局怎么辦? 綁定怎么辦?。
1.將List的泛型參數(shù)轉(zhuǎn)移到Adapter中:? ? ? ? ? ? ? ? ? ? ? ? ? ? 泛型類
2.封裝 getCount、getItem、getItemId方法
3.封裝ViewHolder,并解決不同布局控件不統(tǒng)一問題? ? ? ?布局通過type傳入
通用ViewHolder需要找到相應(yīng)的控件? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 通過泛型方法找到控件,tv,image。調(diào)用通過settext,setimager區(qū)分。
通用ViewHolder需要提供方法來設(shè)置相應(yīng)控件的內(nèi)容
數(shù)據(jù)決定采用泛型,布局打算直接構(gòu)造傳第,綁定顯示效果肯定就只能回傳。
封裝步驟:
1.把數(shù)據(jù)封裝
2.把控件封裝
3.封裝多類型
4.封裝點(diǎn)擊事件
總結(jié):主要分裝ViewHodler。
publicabstractclassBaseRecyclerViewAdapter<T>extendsRecyclerView.Adapter<MyViewHolder>{
privateList<T>mList;//數(shù)據(jù)源
protectedLayoutInflatermInflater;
privateContextmContext;
// 布局怎么辦?直接從構(gòu)造里面?zhèn)鬟f
privateintmLayoutId;
// 多布局支持
privateMultiTypeSupportmMultiTypeSupport;
publicBaseRecyclerViewAdapter(List<T>mList,Contextcontext,intlayoutId) {
this.mList=mList;
this.mContext=context;
this.mInflater=LayoutInflater.from(mContext);
this.mLayoutId=layoutId;
? ? }
publicBaseRecyclerViewAdapter(List<T>mList,Contextcontext,MultiTypeSupportmMultiTypeSupport) {
this(mList,context,-1);
this.mMultiTypeSupport=mMultiTypeSupport;
? ? }
@NonNull
@Override
publicMyViewHolderonCreateViewHolder(@NonNullViewGroupparent,intviewType) {
if(mMultiTypeSupport!=null){
mLayoutId=viewType;
? ? ? ? }
// 先inflate數(shù)據(jù)
ViewitemView=mInflater.inflate(mLayoutId,parent,false);
// 返回ViewHolder
MyViewHolderholder=newMyViewHolder(itemView);
returnholder;
? ? }
@Override
publicintgetItemViewType(intposition) {
if(mMultiTypeSupport!=null) {
returnmMultiTypeSupport.getLayoutId(mList.get(position),position);
? ? ? ? }
returnsuper.getItemViewType(position);
? ? }
@Override
publicvoidonBindViewHolder(@NonNullMyViewHolderholder,intposition) {
// 設(shè)置點(diǎn)擊和長按事件
if(mItemClickListener!=null) {
holder.itemView.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(Viewv) {
mItemClickListener.onItemClick(position);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
if(mLongClickListener!=null) {
holder.itemView.setOnLongClickListener(newView.OnLongClickListener() {
@Override
publicbooleanonLongClick(Viewv) {
returnmLongClickListener.onLongClick(position);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
convert(holder,mList.get(position));
? ? }
/**
? ? * 利用抽象方法回傳出去,每個(gè)不一樣的Adapter去設(shè)置
? ? *
? ? * @param item 當(dāng)前的數(shù)據(jù)
? ? */
publicabstractvoidconvert(MyViewHolderholder,Titem);
@Override
publicintgetItemCount() {
returnmList.size();
? ? }
/***************
? ? * 設(shè)置條目點(diǎn)擊和長按事件
? ? *********************/
publicOnItemClickListenermItemClickListener;
publicOnLongClickListenermLongClickListener;
publicvoidsetOnItemClickListener(OnItemClickListeneritemClickListener) {
this.mItemClickListener=itemClickListener;
? ? }
publicvoidsetOnLongClickListener(OnLongClickListenerlongClickListener) {
this.mLongClickListener=longClickListener;
? ? }
}
publicinterfaceMultiTypeSupport<T>{
// 根據(jù)當(dāng)前位置或者條目數(shù)據(jù)返回布局
publicintgetLayoutId(Titem,intposition);
}
使用的時(shí)候,傳遞多類型的布局id。然后設(shè)置控件的id
publicclassPengAdapterextendsBaseRecyclerViewAdapter<String>{
publicPengAdapter(List<String>mList,Contextcontext,intlayoutId) {
super(mList,context,layoutId);
? ? }
publicPengAdapter(List<String>mList,Contextcontext,MultiTypeSupportmMultiTypeSupport) {
super(mList,context,mMultiTypeSupport);
? ? }
@Override
publicvoidconvert(MyViewHolderholder,Stringitem) {
holder.setText(R.id.tv_content,item);
? ? }
}