RecyclerView-->通用的Adapter
打造一個通用的Adapter,可以減少我們的程式碼量,通用的Adapter需要我們考慮三個問題:
- 資料的型別?我們可以採用泛型;
- 佈局?我們可以利用建構函式傳遞;
- 繫結?利用回傳,讓子類實現;
1.Adapter的基本改造
通用Adapter的程式碼如下:
public abstract class CommonRecyclerAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
protected Context mContext;
protected LayoutInflater mInflater;
protected List<T> mDatas;
private int mLayoutId;
public CommonRecyclerAdapter(Context context, List<T> datas, int layoutId) {
this.mContext = context;
this.mInflater = LayoutInflater.from(mContext);
this.mDatas = datas;
this.mLayoutId = layoutId;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(mLayoutId, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (mDatas != null){
convert(holder, mDatas.get(position),position);
}else {
convert(holder, null,position);
}
}
/**
* 利用抽象方法回傳出去,每個不一樣的Adapter去設定
* @param item 當前的資料
*/
public abstract void convert(ViewHolder holder, T item,int position);
@Override
public int getItemCount() {
return mDatas == null ? 20:mDatas.size();
}
}
實際使用如下:
public class TestAdapter extends CommonRecyclerAdapter<String> {
public TestAdapter(Context context, List<String> datas) {
super(context,datas,R.layout.item_demo);
}
@Override
public void convert(ViewHolder viewHolder, String bean, int position) {
TextView text = (TextView)viewHolder.itemView.findViewById(R.id.tv_text);
text.setText(String.format("第%d資料", position + 1));
}
}
可以看到程式碼量大大滴減少了。
但是上面使用中我們發現每次呼叫onBindViewHolder都會findViewById,所以我們還需要對ViewHolder進行優化。
2.ViewHolder的優化
優化後的ViewHolder如下:
public class ViewHolder extends RecyclerView.ViewHolder {
//用來存放view減少findviewByid的次數
private SparseArray<View> mViews;
public ViewHolder(@NonNull View itemView) {
super(itemView);
mViews = new SparseArray<>();
}
/**
* 設定TextView文字
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId,CharSequence text){
TextView tv = getView(viewId);
tv.setText(text);
return this;
}
public <T extends View> T getView(int viewId){
View view = mViews.get(viewId);
if (view == null){
view = itemView.findViewById(viewId);
mViews.put(viewId,view);
}
return (T)view;
}
/**
* 設定view是否可見
* @param viewId
* @param visibility
* @return
*/
public ViewHolder setViewVisibility(int viewId,int visibility){
getView(viewId).setVisibility(visibility);
return this;
}
/**
* 設定ImageView資源
* @param viewId
* @param resId
* @return
*/
public ViewHolder setImageResourse(int viewId,int resId){
ImageView imageView = getView(viewId);
imageView.setImageResource(resId);
return this;
}
/**
* 設定條目的點選事件
* @param listener
*/
public void setOnItemClickListener(View.OnClickListener listener){
itemView.setOnClickListener(listener);
}
/**
* 設定圖片通過url,載入圖片使用的第三方可能不一樣,所以定義了HolderImageLoader
* @param viewId
* @param imageLoader
*/
public void setImageByUrl(int viewId,HolderImageLoader imageLoader){
ImageView imageView = getView(viewId);
if (imageLoader == null){
throw new NullPointerException("imageLoader is null!");
}
imageLoader.displayImage(imageView.getContext(),imageView,imageLoader.getImagePath());
}
/**
* 設定條目的長按事件
* @param listener
*/
public void setOnItemLongClickListener(View.OnLongClickListener listener){
itemView.setOnLongClickListener(listener);
}
public static abstract class HolderImageLoader{
private String mImagePath;
public HolderImageLoader(String imagePath){
this.mImagePath = imagePath;
}
public String getImagePath(){
return mImagePath;
}
public abstract void displayImage(Context context,ImageView imageView,String imagePath);
}
}
實際使用:
public class TestAdapter extends CommonRecyclerAdapter<String> {
public TestAdapter(Context context, List<String> datas) {
super(context,datas,R.layout.item_demo);
}
@Override
public void convert(ViewHolder viewHolder, String bean, int position) {
viewHolder.setText(R.id.tv_text,String.format("第%d資料", position + 1))
}
}
3.多佈局的實現
public interface MultiTypeSupport<T> {
public int getLayoutId(T bean,int position);
}
最終的Adapter:
public abstract class CommonRecyclerAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
protected Context mContext;
protected LayoutInflater mInflater;
protected List<T> mDatas;
private int mLayoutId;
//多佈局支援
private MultiTypeSupport mMultiTypeSupport;
public CommonRecyclerAdapter(Context context, List<T> datas, int layoutId) {
this.mContext = context;
this.mInflater = LayoutInflater.from(mContext);
this.mDatas = datas;
this.mLayoutId = layoutId;
}
//多佈局支援
public CommonRecyclerAdapter(Context context, List<T> datas, MultiTypeSupport multiTypeSupport) {
this(context, datas, -1);
mMultiTypeSupport = multiTypeSupport;
}
@Override
public int getItemViewType(int position) {
if (mMultiTypeSupport != null)
return mMultiTypeSupport.getLayoutId(mDatas.get(position), position);
return super.getItemViewType(position);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (mMultiTypeSupport != null)
mLayoutId = viewType;
View itemView = mInflater.inflate(mLayoutId, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
if (mItemClickListener != null) {
holder.setOnItemClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mItemClickListener.OnItemClick(position);
}
});
}
if (mLongClickListener != null) {
holder.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
return mLongClickListener.onLongClick(position);
}
});
}
if (mDatas != null) {
convert(holder, mDatas.get(position), position);
} else {
convert(holder, null, position);
}
}
/**
* 利用抽象方法回傳出去,每個不一樣的Adapter去設定
*
* @param item 當前的資料
*/
public abstract void convert(ViewHolder holder, T item, int position);
@Override
public int getItemCount() {
return mDatas == null ? 20 : mDatas.size();
}
/***************
* 設定條目點選和長按事件
*********************/
public OnItemClickListener mItemClickListener;
public OnLongClickListener mLongClickListener;
public void setOnItemClickListener(OnItemClickListener itemClickListener) {
this.mItemClickListener = itemClickListener;
}
public void setOnLongClickListener(OnLongClickListener longClickListener) {
this.mLongClickListener = longClickListener;
}
public interface OnItemClickListener {
void OnItemClick(int position);
}
public interface OnLongClickListener {
boolean onLongClick(int position);
}
}
相關文章
- recycleView通用AdapterViewAPT
- Kotlin 打造一個RecyclerView的通用Adapter(一)KotlinViewAPT
- Kotlin 寫一個通用Adapter (二)KotlinAPT
- RecyclerView-->點選和長按事件View事件
- Adapter PatternAPT
- RecyclerView.Adapter的封裝(RecyclerAdapter)ViewAPT封裝
- 【Android Adapter】是時候開啟Adapter新時代了AndroidAPT
- VirtualBox Host-only Adapter,Failed to create the host-only adapter 轉APTAI
- Istio Mixer Adapter開發 (三)自定義Mixer Grpc Adapter部署APTRPC
- RecyclerView的Adapter中attach和detach探索ViewAPT
- 介面卡模式(adapter pattern)模式APT
- Adapter-介面卡模式APT模式
- IP Adapter程式碼筆記APT筆記
- Canal adapter 同步 ElasticSearch 記錄APTElasticsearch
- Android RecyclerView中Adapter和ViewHoAndroidViewAPT
- Camunda 流程引擎的一種 Adapter 層實現APT
- Android:打造“萬能”Adapter與ViewHolderAndroidAPTView
- Istio Mixer Adapter開發系列 - 概述APT
- 如何實現 axios 的自定義介面卡 adapteriOSAPT
- CAT Caterpillar ET Diagnostic Adapter III User ExperienceAPT
- 使用canal.adapter同步資料到MySQLAPTMySql
- VirtualBox Network設定的NAT和Bridged Adapter模式區別APT模式
- 用委託者模式實現的多型別Adapter模式多型型別APT
- 深入解讀Prometheus Adapter:雲原生監控的核心元件PrometheusAPT元件
- 通用查詢的抽象抽象
- RecyclerView基礎(一)Adapter與Holder的封裝之RvAdapter,RvHolderViewAPT封裝
- PHP設計模式-Adapter 介面卡模式PHP設計模式APT
- Android開發——說說Adapter那點事AndroidAPT
- 微信小遊戲開發(6)-Adapter遊戲開發APT
- Lumen 報錯 : Class 'League\Flysystem\Adapter\Local' not foundAPT
- GoldenGate for Java adapter介紹二(程式碼篇)GoJavaAPT
- GoldenGate for Java Adapter介紹一(原理篇)GoJavaAPT
- 基於 Multitype 開源庫封裝更好用的RecyclerView.Adapter封裝ViewAPT
- Laravel 通用化的 CURDLaravel
- 《設計模式》 - 5. 介面卡模式( Adapter )設計模式APT
- Scan Your Truck Using Nexiq Adapter: Simplifying Your Diagnostic ProcessAPT
- 設計模式之介面卡模式(adapter pattern)設計模式APT
- Istio Mixer Adapter開發 (二)Istio環境搭建APT