Android單個RecyclerView實現(xiàn)列表嵌套的效果
很多時候會遇到一種需求,列表里面有列表,像這種需求之前一般都是用多個列表控件互相嵌套來實現(xiàn),但是這樣很容易出現(xiàn)一些問題,例如滾動沖突、數(shù)據(jù)顯示不全、多余的邏輯處理等。后來發(fā)現(xiàn),一個recyclerview就可以實現(xiàn)列表嵌套的效果,這里需要用到recyclerview的多布局功能。
效果圖:

recyclerview的多布局涉及到的主要方法是getItemViewType,作用是設置每個item要顯示的布局類型。之前不了解的時候,都是直接用數(shù)學邏輯直接去計算,多少個position后顯示什么布局,這種方式適合在邏輯簡單的時候,但是一旦邏輯稍微有點復雜就果斷不能用,可能會自己埋下深坑不說,還不好維護,所以這邊把布局類型放在數(shù)據(jù)對象中。
1. 定義多布局對象的基類:
public class BaseMulDataModel {
protected int type;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
type是該對象對應的布局類型。
2. recyclerview數(shù)據(jù)的顯示放在ViewHolder中,定義Holder基類
public abstract class BaseMulViewHolder<T extends BaseMulDataModel> extends RecyclerView.ViewHolder {
public BaseMulViewHolder(View itemView) {
super(itemView);
}
protected abstract void bindData(T dataModel);
}
這里面多布局中可能涉及到的多個對象,所以基類中的對象類型使用泛型定義,必須是多布局對象基類的子類,這樣在后面數(shù)據(jù)和控件綁定的時候比較方便。
3. 開始創(chuàng)建多布局適配器
public class MullayoutAdapter extends RecyclerView.Adapter<BaseMulViewHolder> {
/**
* 定義三種布局類型
*/
public static final int TYPE_ONE = 1;
public static final int TYPE_TWO = 2;
public static final int TYPE_THREE = 3;
/**
* 數(shù)據(jù)集合
*/
private List<BaseMulDataModel> mList;
@Override
public BaseMulViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//根據(jù)不同的布局類型,設置創(chuàng)建相關的holder
switch (viewType) {
case TYPE_ONE:
return new ViewHolderOne(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_holder1, parent, false));
case TYPE_TWO:
return new ViewHolderTwo(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_holder2, parent, false));
case TYPE_THREE:
return new ViewHolderThree(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_holder3, parent, false));
}
return null;
}
@Override
public void onBindViewHolder(BaseMulViewHolder holder, int position) {
//綁定數(shù)據(jù)
holder.bindData(mList.get(position));
}
@Override
public int getItemCount() {
return mList.size();
}
@Override
public int getItemViewType(int position) {
return mList.get(position).getType();
}
/**
* 設置數(shù)據(jù)
*
* @param list
*/
public void setDatas(List<BaseMulDataModel> list) {
mList = list;
notifyDataSetChanged();
}
public List<BaseMulDataModel> getDatas() {
return mList;
}
/**
* 設置第一個布局的數(shù)據(jù)
*/
class ViewHolderOne extends BaseMulViewHolder<OneModel> {
TextView textView;
public ViewHolderOne(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.holder1_tv);
}
@Override
protected void bindData(OneModel dataModel) {
textView.setText(dataModel.getTitle());
}
}
/**
* 設置第二個布局的數(shù)據(jù)
*/
class ViewHolderTwo extends BaseMulViewHolder<TwoModel> {
ImageView imageView;
public ViewHolderTwo(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.holder2_iv);
}
@Override
protected void bindData(TwoModel dataModel) {
imageView.setImageResource(dataModel.getRes());
}
}
/**
* 設置第三個布局的數(shù)據(jù)
*/
class ViewHolderThree extends BaseMulViewHolder<ThreeModel> {
TextView textView;
public ViewHolderThree(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.holder3_tv);
}
@Override
protected void bindData(ThreeModel dataModel) {
textView.setText(dataModel.getNote());
}
}
}
首先這邊涉及到布局類型:頭部、內(nèi)容列表、底部。定義三種類型
/** * 定義三種布局類型 */ public static final int TYPE_ONE = 1; public static final int TYPE_TWO = 2; public static final int TYPE_THREE = 3;
根據(jù)布局類型來創(chuàng)建對應的ViewHolder對象
public BaseMulViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//根據(jù)不同的布局類型,設置創(chuàng)建相關的holder
switch (viewType) {
case TYPE_ONE:
return new ViewHolderOne(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_holder1, parent, false));
case TYPE_TWO:
return new ViewHolderTwo(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_holder2, parent, false));
case TYPE_THREE:
return new ViewHolderThree(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_holder3, parent, false));
}
return null;
}
當然事先創(chuàng)建對應的Holder類:
/**
* 設置第一個布局的數(shù)據(jù)
*/
class ViewHolderOne extends BaseMulViewHolder<OneModel> {
TextView textView;
public ViewHolderOne(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.holder1_tv);
}
@Override
protected void bindData(OneModel dataModel) {
textView.setText(dataModel.getTitle());
}
}
這邊把泛型對象擦除,使用具體對象OneModel來作為當前的數(shù)據(jù)對象。OneModel是BaseMulDataModel的基類。
OneModel的定義:
public class OneModel extends BaseMulDataModel {
private String title;
public OneModel(String title, int type) {
this.title = title;
this.type = type;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
4. 進行數(shù)據(jù)處理
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recycler.setLayoutManager(layoutManager);
final MullayoutAdapter adapter = new MullayoutAdapter();
recycler.setAdapter(adapter);
//數(shù)據(jù)處理
List<BaseMulDataModel> mList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
mList.add(new OneModel("頭部" + i, MullayoutAdapter.TYPE_ONE));
for (int j = 0; j < 3; j++) {
mList.add(new TwoModel(R.mipmap.ic_launcher, MullayoutAdapter.TYPE_TWO));
}
mList.add(new ThreeModel("底部" + i, MullayoutAdapter.TYPE_THREE));
}
adapter.setDatas(mList);
}
}
后臺返回的數(shù)據(jù)一般不是我們想要的格式,所以自己進行數(shù)據(jù)的拆分處理,數(shù)據(jù)的處理方式很大程度上決定了代碼編寫的難易度。
這邊的數(shù)據(jù)處理是把簡單地需要顯示的數(shù)據(jù)按順序依次放入到數(shù)據(jù)集合list中,然后給每個對象設置type,定義它所需要的布局類型,數(shù)據(jù)的處理方式比較簡單,但是能應付很多的場景。在購物車場景中,一般也是像示例一樣,有頭部、內(nèi)容、底部。后臺返回的數(shù)據(jù)可能是一個json對象包含了所有(頭部、內(nèi)容列表、底部),這邊把他拆分成三部分,在依次放入集合中顯示。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android中使用AsyncTask實現(xiàn)下載文件動態(tài)更新進度條功能
這篇文章主要介紹了AsyncTask用法解析-下載文件動態(tài)更新進度條,需要的朋友可以參考下2017-08-08
Android中實現(xiàn)下載和解壓zip文件功能代碼分享
這篇文章主要介紹了Android中實現(xiàn)下載和解壓zip文件功能代碼分享,本文直接給出了實現(xiàn)代碼,需要的朋友可以參考下2015-03-03
Android開發(fā)之imageView圖片按比例縮放的實現(xiàn)方法
這篇文章主要介紹了Android開發(fā)之imageView圖片按比例縮放的實現(xiàn)方法,較為詳細的分析了Android中ImageView控件的scaleType屬性控制圖片縮放的具體用法,需要的朋友可以參考下2016-01-01
Android開發(fā)之InetAddress基礎入門簡介與源碼實例
這篇文章主要介紹了Android開發(fā)之InetAddress基礎入門簡介,需要的朋友可以參考下2020-03-03
Android自定義實現(xiàn)BaseAdapter的優(yōu)化布局
這篇文章主要為大家詳細介紹了Android自定義實現(xiàn)BaseAdapter的優(yōu)化布局,感興趣的小伙伴們可以參考一下2016-08-08
Android開發(fā)筆記之: 數(shù)據(jù)存儲方式詳解
本篇文章是對Android中數(shù)據(jù)存儲方式進行了詳細的分析介紹,需要的朋友參考下2013-05-05

