天天看點

RecyclerView 的 RecyclerView.Adapter 通用版的實作

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就實作啦,當你的項目中有好幾個的清單的時候,不妨試試這個,能夠減少你很多的工作量。