先說技術(shù)类浪,然后再嘮叨嘮叨,最近好多東西都憋著···
RecyclerView肌似,就算沒用過也聽過吧费就,各種強大的功能,有了這個以后川队,再也不想用ListView了力细。
曾幾何時,我其實一直很想用RecyclerView固额,但是一度覺得它的配置太復(fù)雜艳汽,明明ListView配置那么簡單了干嘛還有RecyclerView。
直到我真的用上了RecyclerView对雪,還配備了一套強大的RecyclerView工具類,用起來簡直沒誰了米绕。從此不再關(guān)心ListView是啥瑟捣。
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_test"
android:layout_width="match_parent"
android:layout_height="match_parent" />
布局,不多說栅干,也沒啥好說的
初始化迈套,一切從這里開始
上面的定義就不寫了,你們懂的就好碱鳞。
mFocusAdapter = new FocusAdapter(getActivity()); //適配器
mFocusAdapter.setOnItemClickListener(mOnFocusItemClickListener); //點擊事件
mRecyclerView.setAdapter(mFocusAdapter); //添加適配器
mRecyclerView.addItemDecoration(new PriceDividerDecoration(this,
LinearLayoutManager.VERTICAL)); //分割線
mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); //List方式(要用表格布局就一個參數(shù)的事)
//mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));(表格布局桑李,4是代表每行幾項數(shù)據(jù))
下面是點擊事件
/**
* RecycleView列表點擊事件
*/
private OnItemClickListener mOnFocusItemClickListener = new OnItemClickListener() {
@Override
public void onClick(View view, int position, Object item) { //這個很好用,因為把item都帶出來了
}
};
為毛適配器不用加數(shù)據(jù)
為毛適配器可以添加點擊事件
答案都在適配器里面
public class FocusAdapter extends BaseRecyclerViewAdapter<Bean, BaseRecyclerViewHolder> {
/**
* @param context
*/
public FocusAdapter(Context context) {
super(context);
}
@Override
protected void bindDataToItemView(BaseRecyclerViewHolder holder, int position, Bean item) {
holder.setText(R.id.tv_test,item.getClassName());//設(shè)置數(shù)據(jù)
}
@Override
public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new BaseRecyclerViewHolder(inflateItemView(parent, R.layout.test)); //布局
}
}
看到?jīng)],估計也看不到啥贵白,就是因為繼承了一個BaseRecyclerViewAdapter這個東西
要注意的是你們adapter的布局文件記得寬度和高度要自適應(yīng)率拒,要不分分鐘顯示出問題
上代碼
public abstract class BaseRecyclerViewAdapter<T, VH extends BaseRecyclerViewAdapter.SparseArrayViewHolder> extends RecyclerView.Adapter<VH> {
/**
* click listener
*/
protected OnItemClickListener mOnItemClickListener;
/**
* long click listener
*/
protected OnItemLongClickListener mOnItemLongClickListener;
/**
* data
*/
protected List<T> mList = new ArrayList<T>();
protected Context mContext;
/**
*/
public BaseRecyclerViewAdapter(Context context) {
this.mContext = context;
}
/* public void addAll(ArrayList<T> list) {
int lastIndex = this.mList.size();
if (this.mList.addAll(list)) {
notifyItemRangeInserted(lastIndex, list.size());
}
}*/
public void addAll(List<T> list) {
int lastIndex = this.mList.size();
if (this.mList.addAll(list)) {
notifyItemRangeInserted(lastIndex, list.size());
}
}
public void update(List<T> mDatas) {
this.mList.addAll(mDatas);
notifyDataSetChanged();
}
public void updateData(List<T> mDatas) {
this.mList=mDatas;
notifyDataSetChanged();
}
public void clear() {
this.mList.clear();
notifyDataSetChanged();
}
public void clearList() {
this.mList.clear();
}
/**
* get a item by index
*
* @param position
* @return
*/
public T getItem(int position) {
return mList.get(position);
}
@Override
public void onBindViewHolder(VH holder, int position, List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
}
@Override
public int getItemCount() {
return mList.size();
}
public List<T> getDatas() {
return mList;
}
/**
* set a long click listener
*
* @param onItemLongClickListener
*/
public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
mOnItemLongClickListener = onItemLongClickListener;
}
/**
* set a click listener
*
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
/**
* inflate a view by viewgroup ,id ,etc
*
* @param viewGroup
* @param layoutId
* @return
*/
protected View inflateItemView(ViewGroup viewGroup, int layoutId) {
return inflateItemView(viewGroup, layoutId, false);
}
/**
* inflate a view by viewgroup ,id ,etc
*
* @param viewGroup
* @param layoutId
* @param attach
* @return
*/
protected View inflateItemView(ViewGroup viewGroup, int layoutId, boolean attach) {
return LayoutInflater.from(viewGroup.getContext()).inflate(layoutId, viewGroup, attach);
}
/**
* a final function to avoid you override
* use template design pattern
*
* @param vh
* @param position
*/
@Override
public final void onBindViewHolder(VH vh, int position) {
final T item = getItem(position);
bindDataToItemView(vh, position, item);
bindItemViewClickListener(vh, position, item);
}
/**
* bind data to itemview
*
* @param vh viewholder
* @param item item
*/
protected abstract void bindDataToItemView(VH vh, int position, T item);
/**
* bind click listner to itemview
*
* @param vh viewholder
* @param item item
*/
protected final void bindItemViewClickListener(VH vh, final int position, final T item) {
if (mOnItemClickListener != null) {
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnItemClickListener.onClick(view, position, item);
}
});
}
if (mOnItemLongClickListener != null) {
vh.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mOnItemLongClickListener.onLongClick(v, position, item);
return true;
}
});
}
}
/**
* BaseViewHolder
* using bindViewById(View view,int id) function to handle the relations between view and viewId
*/
public abstract static class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(View itemView) {
super(itemView);
findView();
}
/**
* you need to override this method to bind view in the viewholder
* you'd better use bindViewById(View view,int id)
*/
protected abstract void findView();
/**
* generic function to findViewById
*
* @param id viewId
* @return the view found
*/
protected <T extends View> T findViewById(int id) {
return (T) itemView.findViewById(id);
}
}
public static class SparseArrayViewHolder extends RecyclerView.ViewHolder {
private final SparseArray<View> views;
public SparseArrayViewHolder(View itemView) {
super(itemView);
views = new SparseArray<View>();
}
public <T extends View> T getView(int id) {
View view = views.get(id);
if (view == null) {
view = itemView.findViewById(id);
views.put(id, view);
}
return (T) view;
}
public SparseArrayViewHolder setText(int viewId, CharSequence value) {
TextView view = getView(viewId);
view.setText(value);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setSpannableText(int viewId, Spannable value) {
TextView view = getView(viewId);
view.setText(value);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setTextColor(int viewId, int textColor) {
TextView view = getView(viewId);
view.setTextColor(textColor);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setImageResource(int viewId, int imageResId) {
ImageView view = getView(viewId);
view.setImageResource(imageResId);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setBitmap(int viewId, Bitmap bm) {
ImageView view = getView(viewId);
view.setImageBitmap(bm);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setBackgroundColor(int viewId, int color) {
View view = getView(viewId);
view.setBackgroundColor(color);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setBackgroundResource(int viewId, int backgroundRes) {
View view = getView(viewId);
view.setBackgroundResource(backgroundRes);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setVisible(int viewId, boolean visible) {
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
View view = getView(viewId);
view.setOnTouchListener(listener);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
View view = getView(viewId);
view.setOnLongClickListener(listener);
return SparseArrayViewHolder.this;
}
public SparseArrayViewHolder setTag(int viewId, Object tag) {
View view = getView(viewId);
view.setTag(tag);
return SparseArrayViewHolder.this;
}
}
}
還有一個
public class BaseRecyclerViewHolder extends BaseRecyclerViewAdapter.SparseArrayViewHolder {
public BaseRecyclerViewHolder(View itemView) {
super(itemView);
}
}
不用管是啥 復(fù)制粘貼拿去用吧
還是挺長的,因為里面封裝了挺多的方法禁荒。
直接用就好猬膨,不懂得用兩遍就差不多了,或者用好getView和setText呛伴,就差不多了勃痴。
再來個分割線
public class PriceDividerDecoration extends RecyclerView.ItemDecoration{
/*
* RecyclerView的布局方向,默認先賦值
* 為縱向布局
* RecyclerView 布局可橫向热康,也可縱向
* 橫向和縱向?qū)?yīng)的分割想畫法不一樣
* */
private int mOrientation = LinearLayoutManager.VERTICAL ;
/**
* item之間分割線的size沛申,默認為1
*/
private int mItemSize =1;
/**
* 繪制item分割線的畫筆,和設(shè)置其屬性
* 來繪制個性分割線
*/
private Paint mPaint ;
/**
* 構(gòu)造方法傳入布局方向姐军,不可不傳
* @param context
* @param orientation
*/
public PriceDividerDecoration(Context context,int orientation) {
this.mOrientation = orientation;
if(orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL){
throw new IllegalArgumentException("請傳入正確的參數(shù)") ;
}
// mItemSize = (int) TypedValue.applyDimension(mItemSize, TypedValue.COMPLEX_UNIT_DIP,context.getResources().getDisplayMetrics());
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG) ;
mPaint.setColor(context.getResources().getColor(R.color.horizontal_line_color));
/*設(shè)置填充*/
mPaint.setStyle(Paint.Style.FILL);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if(mOrientation == LinearLayoutManager.VERTICAL){
drawVertical(c,parent) ;
}else {
drawHorizontal(c,parent) ;
}
}
/**
* 繪制縱向 item 分割線
* @param canvas
* @param parent
*/
private void drawVertical(Canvas canvas,RecyclerView parent){
final int left = parent.getPaddingLeft() ;
final int right = parent.getMeasuredWidth() - parent.getPaddingRight() ;
final int childSize = parent.getChildCount() ;
for(int i = 0 ; i < childSize ; i ++){
final View child = parent.getChildAt( i ) ;
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + layoutParams.bottomMargin ;
final int bottom = top + mItemSize ;
canvas.drawRect(left,top,right,bottom,mPaint);
}
}
/**
* 繪制橫向 item 分割線
* @param canvas
* @param parent
*/
private void drawHorizontal(Canvas canvas,RecyclerView parent){
final int top = parent.getPaddingTop() ;
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom() ;
final int childSize = parent.getChildCount() ;
for(int i = 0 ; i < childSize ; i ++){
final View child = parent.getChildAt( i ) ;
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + layoutParams.rightMargin ;
final int right = left + mItemSize ;
canvas.drawRect(left,top,right,bottom,mPaint);
}
}
/**
* 設(shè)置item分割線的size
* @param outRect
* @param view
* @param parent
* @param state
*/
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if(mOrientation == LinearLayoutManager.VERTICAL){
outRect.set(0,0,0,1);
}else {
outRect.set(0,0,1,0);
}
}
}
很好都齊全了
最后還有一行代碼是添加數(shù)據(jù)的
focusAdapter.update(list<Bean>)
這里注意下,更新數(shù)據(jù)用的是list列表铁材,adapter里面加載數(shù)據(jù)配置的Bean是單個的數(shù)據(jù)。
再來個單選事件庶弃,用RecyclerView實現(xiàn)單選衫贬,這個找了挺久的
private int hSelect =-1; //記錄狀態(tài),初始化為-1
mAdapter.setOnItemClickListener(new com.xinsundoc.patient.adapter.base.OnItemClickListener() {
@Override
public void onClick(View view, int position, Object item) {
if (hSelect!=-1)hRecyclerView.findViewHolderForAdapterPosition(hSelect)
.itemView.setBackgroundColor(Color.WHITE); //不等于-1就找到上一次記錄的那個item歇攻,并設(shè)置背景白色(就是取消選中)
view.setBackgroundResource(R.color.gray);//設(shè)置當前背景色為選中狀態(tài)
hSelect=position; //記錄當前item為上一次item
}
});
可能邏輯介紹的不是很清楚固惯,就三行代碼,走個幾遍就知道了缴守。
好咯葬毫,那么強大的RecyclerView,為嘛不用咧是吧屡穗,復(fù)制粘貼好工具類以后感覺配置比ListView都簡單了贴捡,用起來各種方便各種爽啊。
本來想嘮叨下的村砂,想想還是另開一篇文章嘮叨下好了···