你為什么不用RecyclerView

先說技術(shù),然后再嘮叨嘮叨,最近好多東西都憋著···

RecyclerView,就算沒用過也聽過吧,各種強(qiáng)大的功能,有了這個(gè)以后,再也不想用ListView了。

曾幾何時(shí),我其實(shí)一直很想用RecyclerView,但是一度覺得它的配置太復(fù)雜,明明ListView配置那么簡單了干嘛還有RecyclerView。

直到我真的用上了RecyclerView,還配備了一套強(qiáng)大的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);     //點(diǎn)擊事件
        mRecyclerView.setAdapter(mFocusAdapter);                //添加適配器
        mRecyclerView.addItemDecoration(new PriceDividerDecoration(this,  
                LinearLayoutManager.VERTICAL));             //分割線
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));   //List方式(要用表格布局就一個(gè)參數(shù)的事)
//mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));(表格布局,4是代表每行幾項(xiàng)數(shù)據(jù))

下面是點(diǎn)擊事件

    /**
     * RecycleView列表點(diǎn)擊事件
     */
    private OnItemClickListener mOnFocusItemClickListener = new OnItemClickListener() {
        @Override
        public void onClick(View view, int position, Object item) {    //這個(gè)很好用,因?yàn)榘裪tem都帶出來了

        }
    };

為毛適配器不用加數(shù)據(jù)
為毛適配器可以添加點(diǎn)擊事件
答案都在適配器里面

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)],估計(jì)也看不到啥,就是因?yàn)槔^承了一個(gè)BaseRecyclerViewAdapter這個(gè)東西
要注意的是你們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;
        }


    }
}

還有一個(gè)

public class BaseRecyclerViewHolder extends BaseRecyclerViewAdapter.SparseArrayViewHolder {

    public BaseRecyclerViewHolder(View itemView) {
        super(itemView);
    }
}

不用管是啥 復(fù)制粘貼拿去用吧

還是挺長的,因?yàn)槔锩娣庋b了挺多的方法。
直接用就好,不懂得用兩遍就差不多了,或者用好getView和setText,就差不多了。

再來個(gè)分割線

public class PriceDividerDecoration extends RecyclerView.ItemDecoration{

    /*
    * RecyclerView的布局方向,默認(rèn)先賦值
    * 為縱向布局
    * RecyclerView 布局可橫向,也可縱向
    * 橫向和縱向?qū)?yīng)的分割想畫法不一樣
    * */
    private int mOrientation = LinearLayoutManager.VERTICAL ;

    /**
     * item之間分割線的size,默認(rèn)為1
     */
    private int mItemSize =1;

    /**
     * 繪制item分割線的畫筆,和設(shè)置其屬性
     * 來繪制個(gè)性分割線
     */
    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是單個(gè)的數(shù)據(jù)。

再來個(gè)單選事件,用RecyclerView實(shí)現(xiàn)單選,這個(gè)找了挺久的

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就找到上一次記錄的那個(gè)item,并設(shè)置背景白色(就是取消選中)
                view.setBackgroundResource(R.color.gray);//設(shè)置當(dāng)前背景色為選中狀態(tài)
                hSelect=position;         //記錄當(dāng)前item為上一次item
            }
        });

可能邏輯介紹的不是很清楚,就三行代碼,走個(gè)幾遍就知道了。

好咯,那么強(qiáng)大的RecyclerView,為嘛不用咧是吧,復(fù)制粘貼好工具類以后感覺配置比ListView都簡單了,用起來各種方便各種爽啊。

本來想嘮叨下的,想想還是另開一篇文章嘮叨下好了···

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容