RecyclerView 的 RecyclerView.Adapter 通用版的實作(有加載更多的功能)
Android5.0給我們帶來了RecyclerView 他的靈活性非常強,可以替代Listview和GridView,本文主要說說他的擴充卡的使用,下面是自己封裝的一個通用版的擴充卡(),廢話不多說,看代碼:
//這個Adapter裡面有兩個抽象方法
public abstract class MyRecycleViewAdapter<T> extends RecyclerView.Adapter {
private static final int TYPE_ITEM = ;
private static final int TYPE_FOOTER = ;
private List<T> list;//資料集合
private int itemLayout;//item的布局
private Context context;
private boolean isNeedMore;//是否需要加載更多的view
public boolean isNeedMore() {
return isNeedMore;
}
public void setIsNeedMore(boolean isNeedMore) {
this.isNeedMore = isNeedMore;
}
/**
* item的點選和長按監聽
*/
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
//構造器list:要加載的資料集合,itemlayout:item的布局(R.layout.item),isNeedMore:是否需要加載更多的功能(false:不需要,true:需要)
public MyRecycleViewAdapter(List<T> list,int itemLayout,Context context,boolean isNeedMore){
this.list = list;
this.itemLayout = itemLayout;
this.context = context;
this.isNeedMore = isNeedMore;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public int getItemLayout() {
return itemLayout;
}
public void setItemLayout(int itemLayout) {
this.itemLayout = itemLayout;
}
@Override
public int getItemViewType(int position) {
if(!isNeedMore) {
return super.getItemViewType(position);
}
if (position + == getItemCount()) {
return TYPE_FOOTER;
} else {
return TYPE_ITEM;
}
}
//1、第一步,先在onCreateViewHolder裡面添加item的布局,添加到RecyclerView裡面
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_FOOTER) {
//傳回加載更多的布局的holder
return new FooterViewHolder(
LayoutInflater.from(parent.getContext()).inflate(
R.layout.recycle_foot_view, parent, false));
}else {
//傳回item的布局的holder
View view = LayoutInflater.from(context).inflate(itemLayout, parent, false);
return new MyViewHolder(view);
}
}
//3、第三步,把ViewHolder傳遞到onBindViewHolder,進行item的資料綁定
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
//((MyViewHolder) holder).item.setText(position + "");
if(TYPE_ITEM == getItemViewType(position)
|| super.getItemViewType(position) == getItemViewType(position)) {
Log.e("TAG", "自定義的adapter的item設定點選事件");
//當然這裡也可以使用裡面寫的自定義接口的方法來實作,本人覺得
//這樣在使用的時候會更簡潔,不需要設定adapter的監聽
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setPositionClick(position);
}
});
//長按監聽
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return false;
}
});
initData((MyViewHolder) holder, position);
}
// holder.itemView.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// int position = holder.getLayoutPosition();
// onItemClickListener.onItemClick(holder.itemView, position);
// }
// });
// holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
// @Override
// public boolean onLongClick(View v) {
// int position = holder.getLayoutPosition();
// onItemClickListener.onItemLongClick(holder.itemView, position);
// return false;
// }
// });
}
@Override
public int getItemCount() {
if(isNeedMore) {
return list.size()==?:list.size()+;
}else {
return list.size();
}
}
/**
*itemview 的點選事件(抽象方法)
* @param position
*/
protected abstract void setPositionClick(int position);
/**
* 對item進行加載資料
* @param holder recycleview的ViewHolder position位置
* @param position
*/
protected abstract void initData(MyViewHolder holder, int position);
//2、第二步:在ViewHolder裡面初始化視圖
//如果你的item布局裡面有别的視圖可以自己添加對應的方法就是了
//目前裡面沒有寫那麼多
public class MyViewHolder extends RecyclerView.ViewHolder {
private View findView;
private View convertView;
private SparseArray<Object> tags;
//用來替代Map<Integer,Object>的容器, 效率比map高
private SparseArray<View> views;
public MyViewHolder(View itemView) {
super(itemView);
this.convertView = itemView;
this.findView = itemView;
tags = new SparseArray<>();
views = new SparseArray<View>();
}
public View getConverView() {
return convertView;
}
public View getFindView() {
return findView;
}
// /**
// * 根據視圖id得到對應的視圖對象
// * @param viewId
// * @return
// */
// public <T extends View> T getView(@IdRes int viewId) {
// View view = views.get(viewId);
// if (view == null) {
// view = convertView.findViewById(viewId);
// views.put(viewId, view);
// }
// return (T) view;
// }
/**
* 根據 viewId 擷取一個 View 對象
*/
// public View getView(@IdRes int viewId) {
// View view;
// Object viewObj = findView.getTag(viewId);
// if (null != viewObj) {
// view = (View) viewObj;
// } else {
// view = findView.findViewById(viewId);
// findView.setTag(viewId, view);
// }
// return view;
// }
public <T extends View> T getView(@IdRes int viewId) {
View view;
Object viewObj = findView.getTag(viewId);
if (null != viewObj) {
view = (View) viewObj;
} else {
view = findView.findViewById(viewId);
findView.setTag(viewId, view);
}
return (T) view;
}
/**
* 設定指定的id視圖的可見性
* @param viewId
* @param visibility
* @return
*/
public MyViewHolder setViewVisibility(@IdRes int viewId,int visibility){
if(getView(viewId)!=null) {
getView(viewId).setVisibility(visibility);
}
return this;
}
/**
* 根據 viewId 擷取一個 ImageView 對象
*/
public ImageView getImageView(@IdRes int viewId) {
return (ImageView) getView(viewId);
}
/**
* 根據 viewId 擷取一個 TextView 對象
*/
public TextView getTextView(@IdRes int viewId) {
return (TextView) getView(viewId);
}
/**
* 根據 viewId 擷取一個 CheckBox 對象
*/
public CheckBox getCheckBox(@IdRes int viewId) {
return (CheckBox) getView(viewId);
}
/**
* 為指定 viewId 的 ImageView 對象設定圖檔
*/
public MyViewHolder setImageDrawable(@IdRes int viewId, @Nullable Drawable drawable) {
if (getImageView(viewId)!=null) {
getImageView(viewId).setImageDrawable(drawable);
}
return this;
}
/**
* 為指定 viewId 的 ImageView 對象設定圖檔
*/
public MyViewHolder setImageResource(@IdRes int viewId, @DrawableRes int resId) {
if (getImageView(viewId)!=null) {
getImageView(viewId).setImageResource(resId);
}
return this;
}
/**
* 為指定 viewId 的 ImageView 對象設定圖檔
*/
public MyViewHolder setImageBitmap(@IdRes int viewId, Bitmap bitmap) {
if (getImageView(viewId)!=null) {
getImageView(viewId).setImageBitmap(bitmap);
}
return this;
}
/**
* 未指定的viewId 的ImageView 對象設定背景圖檔
* @param viewId
* @param drawable
* @return
*/
public MyViewHolder setImageBackgroud(@IdRes int viewId, @Nullable Drawable drawable) {
if (getImageView(viewId)!=null) {
getImageView(viewId).setBackground(drawable);
}
return this;
}
/**
* 使用 xUtils 為指定 viewId 的 ImageView 對象設定圖檔
*/
public MyViewHolder bindImage(@IdRes int viewId, @NonNull String url) {
bindImage(viewId, url, null);
return this;
}
/**
* 使用 xUtils 為指定 viewId 的 ImageView 對象設定圖檔
*/
public MyViewHolder bindImage(@IdRes int viewId, @NonNull String url, ImageOptions options) {
if (getImageView(viewId)!=null) {
x.image().bind(getImageView(viewId), url, options);
}
return this;
}
/**
* 為指定 viewId 的 TextView 對象設定文字
*/
public MyViewHolder setText(@IdRes int viewId, @StringRes int resid) {
if (getTextView(viewId)!=null) {
getTextView(viewId).setText(resid);
}
return this;
}
/**
* 為指定 viewId 的 TextView 對象設定文字
*/
public MyViewHolder setText(@IdRes int viewId, CharSequence text) {
if (getTextView(viewId)!=null) {
getTextView(viewId).setText(text);
}
return this;
}
public MyViewHolder setTextSize(@IdRes int viewId,@Size int size){
if(getTextView(viewId) != null){
getTextView(viewId).setTextSize(size);
}
return this;
}
/**
* 為指定 viewId 的 TextView 對象設定文字顔色
*/
public MyViewHolder setTextColor(@IdRes int viewId, @ColorInt int color) {
if (getTextView(viewId)!=null) {
getTextView(viewId).setTextColor(color);
}
return this;
}
/**
* 為指定 viewId 的 View 對象設定 TAG
*/
public MyViewHolder setTag(@IdRes int viewId, final Object tag) {
if (getView(viewId)!=null) {
getView(viewId).setTag(tag);
}
return this;
}
/**
* 為指定 viewId 的 View 對象設定背景圖檔
*/
public MyViewHolder setBackgroundResource(@IdRes int viewId, @DrawableRes int resid) {
if (getView(viewId)!=null) {
getView(viewId).setBackgroundResource(resid);
}
return this;
}
/**
* 使用目前 ViewHolder 記錄一個 TAG
*/
public MyViewHolder putTag(int key, final Object tag) {
tags.put(key, tag);
return this;
}
/**
* 從目前 ViewHolder 中取出一個TAG
*/
public Object getTag(int key) {
return tags.get(key);
}
/**
* 為指定 viewId 的 CheckBox 對象設定選中狀态
*/
public MyViewHolder setChecked(@IdRes int viewId, boolean checked) {
if (getCheckBox(viewId)!=null) {
getCheckBox(viewId).setChecked(checked);
}
return this;
}
/**
* 切換指定 viewId 的 CheckBox 的選中狀态
*/
public MyViewHolder toggle(@IdRes int viewId) {
if (getCheckBox(viewId)!=null) {
getCheckBox(viewId).toggle();
}
return this;
}
/**
* 為指定 viewId 的 View 對象設定點選監聽
*/
public MyViewHolder setOnClickListener(@IdRes int viewId, @Nullable View.OnClickListener listener) {
if (getView(viewId)!=null) {
getView(viewId).setOnClickListener(listener);
}
return this;
}
/**
* 為指定 viewId 的 View 對象設定是否可見
*/
public MyViewHolder setVisibile(@IdRes int viewId, boolean visible) {
if (getView(viewId)!=null) {
getView(viewId).setVisibility(visible ? View.VISIBLE : View.GONE);
}
return this;
}
/**
* 為指定 viewId 的 View 對象設定是否可見
*/
public MyViewHolder setVisibility(@IdRes int viewId, int visibility) {
if (getView(viewId)!=null) {
getView(viewId).setVisibility(visibility);
}
return this;
}
/**
* 為指定 viewId 的 View 對象設定布局參數
*/
public MyViewHolder setLayoutParams(@IdRes int viewId, RelativeLayout.LayoutParams params) {
if (getView(viewId)!=null) {
getView(viewId).setLayoutParams(params);
}
return this;
}
}
public class FooterViewHolder extends RecyclerView.ViewHolder {
public FooterViewHolder(View itemView) {
super(itemView);
}
}
}
在來說說具體的使用吧:
private void setRecyclerView(final List data,int layout) {
//線性布局管理器
//false:不進行反轉
//true:進行反轉
final LinearLayoutManager manager = new LinearLayoutManager(ListActivity.this, LinearLayoutManager.VERTICAL, false);
recycle.setLayoutManager(manager);
recycle.setAdapter(new MyRecycleViewAdapter(data, layout, ListActivity.this, true) {
@Override
protected void setPositionClick(int position) {
Intent intent = new Intent(ListActivity.this,DetailedInfoActivity.class);
intent.putExtra("positions",positions);
startActivity(intent);
}
@Override
protected void initData(MyViewHolder holder, int position) {
DetailsInfo info = (DetailsInfo) data.get(position);
setHolderData(data,info,holder,position);
}
});
//滾動監聽,在滾動監聽裡面去實作加載更多的功能
recycle.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int lastVisibleItemPosition = manager.findLastVisibleItemPosition();
if (lastVisibleItemPosition + == recycle.getAdapter().getItemCount()) {
if (!isLoading) {//一個布爾的變量,預設是false
isLoading = true;
Log.e("TAG", "page==" + page);
handler.postDelayed(new Runnable() {
@Override
public void run() {
getDataFromeNet();
}
}, );
} else if (page == ) {
//當沒有更多的資料的時候去掉加載更多的布局
MyRecycleViewAdapter adapter = (MyRecycleViewAdapter) recycle.getAdapter();
adapter.setIsNeedMore(false);
adapter.notifyDataSetChanged();
}
}
}
});
}
private int page=;
/**
* 上拉加載更多
*/
private void getDataFromeNet() {
for (int i = ; i < ; i++) {
DetailsInfo detailsInfo = new DetailsInfo("寶馬4S店"+i+i,"小李","2016.2.3","合格");
data.add(detailsInfo);
}
page++;
if(page!=) {
isLoading = false;
}else {
isLoading = true;
}
recycle.getAdapter().notifyDataSetChanged();
}
好了一個簡單的通用版有加載更多的adapter就實作啦,當你的項目中有好幾個的清單的時候,不妨試試這個,能夠減少你很多的工作量。