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
- ListView 通用 Adapter 封裝ViewAPT封裝
- Kotlin 打造一個RecyclerView的通用Adapter(一)KotlinViewAPT
- Kotlin 寫一個通用Adapter (二)KotlinAPT
- 打造基於Databinding與RecyclerView的通用Adapter類ViewAPT
- 通過Data Binding為RecyclerView打造通用AdapterViewAPT
- 為RecyclerView打造通用Adapter 讓RecyclerView更加好用ViewAPT
- RecyclerView-->點選和長按事件View事件
- AdapterAPT
- RecyclerView Adapter 系列(1):RecyclerView Array AdapterViewAPT
- Adapter中getView的理解!APTView
- Adapter PatternAPT
- 通用RecylerAdapter,內建XRecyclerView,相容上下拉與動畫,高複用,一個Adapter通用所有頁面,支援空頁面,懶人專屬APTView動畫
- 簡化你的列表AdapterAPT
- 關於ADAPTER的問題APT
- Adapter的getView方法詳解APTView
- 多佈局的自定義AdapterAPT
- android adapter的效能小結AndroidAPT
- ListView(1)——各種Adapter的使用ViewAPT
- 【Android Adapter】是時候開啟Adapter新時代了AndroidAPT
- RecyclerView Adapter 優雅封裝,一個Adapter搞定所有列表ViewAPT封裝
- design pattens - adapterAPT
- Adapter最佳實踐APT
- Oracle SOA Suite: AdapterOracleUIAPT
- Istio Mixer Adapter開發 (三)自定義Mixer Grpc Adapter部署APTRPC
- VirtualBox Host-only Adapter,Failed to create the host-only adapter 轉APTAI
- RecyclerView的Adapter中attach和detach探索ViewAPT
- RecyclerView.Adapter的封裝(RecyclerAdapter)ViewAPT封裝
- Fragment的Adapter分析及懶載入FragmentAPT
- 請教一個ADAPTER的問題APT
- 關於網站上的Adapter範例網站APT
- Androidlistview與adapter用法AndroidViewAPT
- 用例子來弄懂AdapterAPT
- 設計模式---Adapter模式設計模式APT
- ListView(2)——自定義AdapterViewAPT
- Disk arrary's adapter in troubleAPT
- 介面卡模式(Adapter)模式APT
- facade 和 adapter 模式的 區別?APT模式