日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

Android RecyclerView设计通用Adapter

發(fā)布時(shí)間:2025/3/18 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android RecyclerView设计通用Adapter 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

RecylerView 的使用頻率現(xiàn)在也算做是很高了吧?使用起來(lái)的確是挺方便的,也容易實(shí)現(xiàn)一些比較好看的效果

一、一般步驟

一般的設(shè)計(jì)流程都是如下所示
首先是需要一個(gè) JavaBean 來(lái)承載數(shù)據(jù),包含的內(nèi)容分別是標(biāo)題還有內(nèi)容

public class Data {private String title;private String content;public Data(String title, String content) {this.title = title;this.content = content;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}}

然后繼承 RecyclerView.Adapter ,并實(shí)現(xiàn)幾個(gè)固定方法

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.MyViewHolder> {private List<Data> dataList;private LayoutInflater layoutInflater;public MyRecyclerAdapter(Context context, List<Data> dataList) {this.dataList = dataList;layoutInflater = LayoutInflater.from(context);}@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View itemView = layoutInflater.inflate(R.layout.item_left, parent, false);return new MyViewHolder(itemView);}@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {holder.tv_title.setText(dataList.get(position).getTitle());holder.tv_content.setText(dataList.get(position).getContent());}@Overridepublic int getItemCount() {return dataList.size();}class MyViewHolder extends RecyclerView.ViewHolder {private TextView tv_title;private TextView tv_content;MyViewHolder(View itemView) {super(itemView);tv_title = (TextView) itemView.findViewById(R.id.tv_title);tv_content = (TextView) itemView.findViewById(R.id.tv_content);}}}

使用到的布局文件

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/tv_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="left"android:textSize="15sp" /><TextViewandroid:id="@+id/tv_content"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="15sp" /><Viewandroid:layout_width="match_parent"android:layout_height="1px"android:background="#abc" /></LinearLayout>

然后再來(lái)為 RecycleView 填充 Adapter

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycleView);recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));List<Data> dataList = new ArrayList<>();for (int i = 0; i < 40; i++) {Data data = new Data("葉應(yīng)是葉", "我也不知道說(shuō)什么好,我也不知道說(shuō)什么好,我也不知道說(shuō)什么好,我也不知道說(shuō)什么好");dataList.add(data);}MyRecyclerAdapter adapter = new MyRecyclerAdapter(this, dataList);recyclerView.setAdapter(adapter);} }

運(yùn)行效果如下


這里寫圖片描述

使用多了會(huì)發(fā)現(xiàn),其實(shí) MyRecyclerAdapter 中幾個(gè)需要實(shí)現(xiàn)的方法其實(shí)都是步驟都是類似的,如果每次都要來(lái)重復(fù)這樣的步驟,那真的是在做無(wú)用的工作了

這里,來(lái)為 RecycleView 設(shè)計(jì)一個(gè)通用 Adapter,取代掉那些重復(fù)的步驟,讓代碼更加簡(jiǎn)潔

二、通用ViewHolder

首先,繼承 RecyclerView.ViewHolder 實(shí)現(xiàn)一個(gè)通用的 ViewHolder
當(dāng)中,使用 SparseArray 來(lái)存放 View 以減少 findViewById 的次數(shù),SparseArray 比 HashMap 更省內(nèi)存,在某些條件下性能會(huì)更好,不過(guò)只能存儲(chǔ) key 為 int 類型的數(shù)據(jù),正好用來(lái)存放資源ID

因?yàn)榱斜眄?xiàng)中一般都是使用 TextView 和 ImageView 兩個(gè)控件,所以這里提供兩個(gè)控件的操作方法。此外,為了監(jiān)聽列表項(xiàng)單擊和雙擊事件,這里再來(lái)自定義一個(gè)接口 onItemCommonClickListener ,用于點(diǎn)擊事件回調(diào)

public class CommonViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener {// SparseArray 比 HashMap 更省內(nèi)存,在某些條件下性能更好,只能存儲(chǔ) key 為 int 類型的數(shù)據(jù),// 用來(lái)存放 View 以減少 findViewById 的次數(shù)private SparseArray<View> viewSparseArray;private onItemCommonClickListener commonClickListener;public CommonViewHolder(View itemView) {super(itemView);itemView.setOnClickListener(this);itemView.setOnLongClickListener(this);viewSparseArray = new SparseArray<>();}/*** 根據(jù) ID 來(lái)獲取 View** @param viewId viewID* @param <T> 泛型* @return 將結(jié)果強(qiáng)轉(zhuǎn)為 View 或 View 的子類型*/public <T extends View> T getView(int viewId) {// 先從緩存中找,找打的話則直接返回// 如果找不到則 findViewById ,再把結(jié)果存入緩存中View view = viewSparseArray.get(viewId);if (view == null) {view = itemView.findViewById(viewId);viewSparseArray.put(viewId, view);}return (T) view;}public CommonViewHolder setText(int viewId, CharSequence text) {TextView tv = getView(viewId);tv.setText(text);return this;}public CommonViewHolder setViewVisibility(int viewId, int visibility) {getView(viewId).setVisibility(visibility);return this;}public CommonViewHolder setImageResource(int viewId, int resourceId) {ImageView imageView = getView(viewId);imageView.setImageResource(resourceId);return this;}protected interface onItemCommonClickListener {void onItemClickListener(int position);void onItemLongClickListener(int position);}public void setCommonClickListener(onItemCommonClickListener commonClickListener) {this.commonClickListener = commonClickListener;}@Overridepublic void onClick(View v) {if (commonClickListener != null) {commonClickListener.onItemLongClickListener(getAdapterPosition());}}@Overridepublic boolean onLongClick(View v) {if (commonClickListener != null) {commonClickListener.onItemClickListener(getAdapterPosition());}return false;} }

三、通用RecyclerAdapter

再來(lái)實(shí)現(xiàn)一個(gè)通用的 RecyclerView.Adapter
因?yàn)椴恢酪褂玫降臄?shù)據(jù)類型是哪一種,也為了更好的適配各種數(shù)據(jù)類型,所以這里需要用到泛型

當(dāng)中,onBindViewHolder(CommonViewHolder holder, int position) 需要我們自己來(lái)操作,所以這里再來(lái)聲明一個(gè)抽象方法 bindData(CommonViewHolder holder, T data) ,由子類來(lái)負(fù)責(zé)實(shí)現(xiàn)綁定操作

public abstract class CommonRecycleAdapter<T> extends RecyclerView.Adapter<CommonViewHolder> {protected LayoutInflater layoutInflater;protected List<T> dataList;protected int layoutId;public CommonRecycleAdapter(Context context, List<T> dataList, int layoutId) {this.layoutInflater = LayoutInflater.from(context);this.dataList = dataList;this.layoutId = layoutId;}@Overridepublic int getItemViewType(int position) {return super.getItemViewType(position);}@Overridepublic CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View itemView = layoutInflater.inflate(layoutId, parent, false);return new CommonViewHolder(itemView);}@Overridepublic void onBindViewHolder(CommonViewHolder holder, int position) {bindData(holder, dataList.get(position));}@Overridepublic int getItemCount() {return dataList.size();}abstract void bindData(CommonViewHolder holder, T data);}

這樣,就有了一個(gè)實(shí)現(xiàn)了基本操作的通用 Adapter
這里再來(lái)看看如何使用它

四、使用通用 Adapter

需要先來(lái)繼承 CommonRecycleAdapter ,只需要實(shí)現(xiàn)一個(gè)方法即可,看起來(lái)簡(jiǎn)潔多了吧
代碼中聲明了兩個(gè)構(gòu)造函數(shù),根據(jù)是否需要用到點(diǎn)擊事件監(jiān)聽來(lái)選擇

public class MyAdapter extends CommonRecycleAdapter<Data> {private CommonViewHolder.onItemCommonClickListener commonClickListener;public MyAdapter(Context context, List<Data> dataList) {super(context, dataList, R.layout.item_left);}public MyAdapter(Context context, List<Data> dataList, CommonViewHolder.onItemCommonClickListener commonClickListener) {super(context, dataList, R.layout.item_left);this.commonClickListener = commonClickListener;}@Overridevoid bindData(CommonViewHolder holder, Data data) {holder.setText(R.id.tv_title, data.getTitle()).setText(R.id.tv_content, data.getContent()).setCommonClickListener(commonClickListener);}}

這里選擇要監(jiān)聽點(diǎn)擊事件

public class MainActivity extends AppCompatActivity implements CommonViewHolder.onItemCommonClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycleView);recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));List<Data> dataList = new ArrayList<>();for (int i = 0; i < 40; i++) {Data data = new Data("葉應(yīng)是葉", "我也不知道說(shuō)什么好,我也不知道說(shuō)什么好,我也不知道說(shuō)什么好,我也不知道說(shuō)什么好");dataList.add(data);}//MyRecyclerAdapter adapter = new MyRecyclerAdapter(this, dataList);MyAdapter adapter = new MyAdapter(this, dataList, this);recyclerView.setAdapter(adapter);}@Overridepublic void onItemClickListener(int position) {Toast.makeText(this, "position:" + position, Toast.LENGTH_SHORT).show();}@Overridepublic void onItemLongClickListener(int position) {Toast.makeText(this, "position:" + position, Toast.LENGTH_SHORT).show();}}

運(yùn)行效果


這里寫圖片描述

五、布局多樣化

前面,CommonRecycleAdapter 已經(jīng)可以為我們節(jié)省很多代碼了,免去了一些重復(fù)性操作
這里,可以再來(lái)更進(jìn)一步使 CommonRecycleAdapter 得以更加通用

舉個(gè)例子,類似微信App的聊天界面那樣,自己發(fā)送的信息和對(duì)方發(fā)送來(lái)的信息位置是一左一右的,也就是說(shuō),這個(gè)聊天列表使用了兩個(gè)不同的布局文件
那么,可以也為 CommonRecycleAdapter 加入支持多布局的功能

為了標(biāo)識(shí)數(shù)據(jù)的不同,在 Data 類中加入一個(gè)新的變量 location

/*** Created by 葉應(yīng)是葉 on 2017/2/25.*/public class Data {private String title;private String content;private String location;public Data(String title, String content) {this.title = title;this.content = content;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}}

之前使用的布局中標(biāo)題是靠左的,這里再定義一個(gè)布局,使標(biāo)題靠右

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/tv_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="right"android:textSize="20sp" /><TextViewandroid:id="@+id/tv_content"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="20sp" /><Viewandroid:layout_width="match_parent"android:layout_height="1px"android:background="#abc" /></LinearLayout>

然后,需要有一個(gè)方法來(lái)判斷哪種數(shù)據(jù)類型需要使用哪種布局,所以再來(lái)定義一個(gè)接口,getLayoutId() 用于返會(huì)布局文件ID

public interface MultiTypeSupport<T> {int getLayoutId(T item, int position);}

修改 CommonRecycleAdapter
如果 multiTypeSupport 不為 null,意思就是要使用到不同的布局文件了,則調(diào)用 getLayoutId() 方法,將其返回值作為 ItemViewType

public abstract class CommonRecycleAdapter<T> extends RecyclerView.Adapter<CommonViewHolder> {protected LayoutInflater layoutInflater;protected List<T> dataList;protected int layoutId;protected MultiTypeSupport<T> multiTypeSupport;public CommonRecycleAdapter(Context context, List<T> dataList, int layoutId) {this.layoutInflater = LayoutInflater.from(context);this.dataList = dataList;this.layoutId = layoutId;}@Overridepublic int getItemViewType(int position) {if (multiTypeSupport != null) {return multiTypeSupport.getLayoutId(dataList.get(position), position);}return super.getItemViewType(position);}@Overridepublic CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {if (multiTypeSupport != null) {layoutId = viewType;}View itemView = layoutInflater.inflate(layoutId, parent, false);return new CommonViewHolder(itemView);}@Overridepublic void onBindViewHolder(CommonViewHolder holder, int position) {bindData(holder, dataList.get(position));}@Overridepublic int getItemCount() {return dataList.size();}abstract void bindData(CommonViewHolder holder, T data);}

修改 MyAdapter 類,實(shí)現(xiàn) MultiTypeSupport 接口,根據(jù) Data 對(duì)象的 location 字段的值,來(lái)決定返回哪個(gè)布局文件的ID

public class MyAdapter extends CommonRecycleAdapter<Data> implements MultiTypeSupport<Data> {private CommonViewHolder.onItemCommonClickListener commonClickListener;public MyAdapter(Context context, List<Data> dataList) {super(context, dataList, R.layout.item_left);}public MyAdapter(Context context, List<Data> dataList, CommonViewHolder.onItemCommonClickListener commonClickListener) {super(context, dataList, R.layout.item_left);this.commonClickListener = commonClickListener;this.multiTypeSupport = this;}@Overridevoid bindData(CommonViewHolder holder, Data data) {holder.setText(R.id.tv_title, data.getTitle()).setText(R.id.tv_content, data.getContent()).setCommonClickListener(commonClickListener);}@Overridepublic int getLayoutId(Data item, int position) {if (item.getLocation().equals("left")) {return R.layout.item_left;}return R.layout.item_right;}}

再來(lái)修改 Activity 中的代碼

public class MainActivity extends AppCompatActivity implements CommonViewHolder.onItemCommonClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycleView);recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));List<Data> dataList = new ArrayList<>();boolean bool = false;for (int i = 0; i < 40; i++) {Data data = new Data("葉應(yīng)是葉", "我也不知道說(shuō)什么好,我也不知道說(shuō)什么好,我也不知道說(shuō)什么好,我也不知道說(shuō)什么好");if (!bool) {data.setLocation("left");} else {data.setLocation("right");}bool = !bool;dataList.add(data);}//MyRecyclerAdapter adapter = new MyRecyclerAdapter(this, dataList);MyAdapter adapter = new MyAdapter(this, dataList, this);recyclerView.setAdapter(adapter);}@Overridepublic void onItemClickListener(int position) {Toast.makeText(this, "position:" + position, Toast.LENGTH_SHORT).show();}@Overridepublic void onItemLongClickListener(int position) {Toast.makeText(this, "position:" + position, Toast.LENGTH_SHORT).show();}}

運(yùn)行效果如下


這里寫圖片描述

可以看到,每隔一行使用到的布局都不一樣

這樣一來(lái),通用的 Adapter 也設(shè)計(jì)完成了,以后即使需要使用到很多種不同的數(shù)據(jù)類型,只要繼承 CommonRecycleAdapter ,實(shí)現(xiàn)一個(gè)或兩個(gè)方法,就可以搞定 Adapter 了

這里提供示例代碼下載:Android RecyclerView設(shè)計(jì)通用Adapter

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的Android RecyclerView设计通用Adapter的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。