RecyclerView

作者: 一只笔 | 来源:发表于2018-06-21 00:05 被阅读9次

    RecyclerVeiw 与ListView区别:


    recyclerView 缓存的Holder而不是View, RecyclerView 不管布局、不管动画、不管分隔、 只管view 的复用,并支持多种刷新模式:notifyDataSetChanged(), notifyItemInserted(position), notifyItemRemoved(position)等多种刷新模式,很大程度提高效率。

    LayoutManager布局管理器:


    LinearLaoutManager:线形
    GridLayoutManager:网格
    StaggeredManager:错乱样式(瀑布流)

    简单使用:


    在xmlk 中的布局

    <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    

    RecyclerView Adapter

    
    
    /**
     * 说明:基本使用
     * 波粒:1050189980 2018/6/20
     */
    public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.MyHolder> {
        protected List<String> mData;
        private Context mContext;
        private LayoutInflater mLayoutInflater;
        OnItemClick mOnItemClick;
    
        public SimpleAdapter(Context contex, List<String> data) {
            mContext = contex;
            mData = data;
            mLayoutInflater = LayoutInflater.from(mContext);
        }
    
        /**
         * 添加数据
         */
        public void add(int position) {
            mData.add(position, "新增");
            notifyItemInserted(position);
        }
    
        /**
         * 删除数据
         */
        public void delete(int position) {
            mData.remove(position);
            notifyItemRemoved(position);
        }
    
        /**
         * 点击事件
         */
        public interface OnItemClick {
            void click(View view, int position);
    
            void longClick(View view, int position);
        }
    
        /**
         * 设置事件
         */
        public void setOnItmeClick(OnItemClick onItmeClick) {
            mOnItemClick = onItmeClick;
        }
    
        /**
         * 创建Holder 对象
         */
        @Override
        public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = mLayoutInflater.inflate(R.layout.itme_simple, parent, false);
            return new MyHolder(view);
        }
    
        /**
         * 绑定Holder 设置数据与事件
         */
        @Override
        public void onBindViewHolder(final MyHolder holder, final int position) {
            holder.textView.setText(mData.get(position));
            if (mOnItemClick != null) {
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mOnItemClick.click(holder.itemView, holder.getLayoutPosition());
                    }
                });
                holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        mOnItemClick.longClick(holder.itemView, holder.getLayoutPosition());
                        return false;
                    }
                });
            }
        }
    
        /**
         * item大小
         */
        @Override
        public int getItemCount() {
            return mData.size();
        }
    
        public class MyHolder extends RecyclerView.ViewHolder {
            TextView textView;
    
            public MyHolder(View itemView) {
                super(itemView);
                textView = itemView.findViewById(R.id.textView);
            }
        }
    }
    
    

    在Activity 中使用

    
    /**
     * RecyclerView  的简单使用
     */
    public class SimpleActivity extends AppCompatActivity {
        RecyclerView mRecyclerView;
        private List<String> mData;
        SimpleAdapter simpleAdapter;
        SimpleStaggeredAdapter simpleStaggeredAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_simple);
            mRecyclerView = findViewById(R.id.recyclerView);
            mData = new ArrayList<>();
            //添加数据源
            for (int i = 'A'; i <= 'z'; i++) {
                mData.add("" + (char) i);
            }
    
            simpleStaggeredAdapter = new SimpleStaggeredAdapter(this, mData);
            simpleAdapter = new SimpleAdapter(this, mData);
            //设置adapter
            mRecyclerView.setAdapter(simpleAdapter);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
            //设置管理器
            mRecyclerView.setLayoutManager(linearLayoutManager);
            //设置动画
            mRecyclerView.setItemAnimator(new DefaultItemAnimator());
            //设置分隔线
            DividerItemDecoration decoration1 = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
            mRecyclerView.addItemDecoration(decoration1);
            //设置事件
            simpleAdapter.setOnItmeClick(new SimpleAdapter.OnItemClick() {
                @Override
                public void click(View view, int position) {
                    Toast.makeText(SimpleActivity.this, "click" + position, Toast.LENGTH_SHORT).show();
                }
    
                @Override
                public void longClick(View view, int position) {
                    simpleAdapter.delete(position);
                    Toast.makeText(SimpleActivity.this, "longClick" + position, Toast.LENGTH_SHORT).show();
                }
            });
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            //导入菜单布局
            getMenuInflater().inflate(R.menu.menu_simple, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            //线型
            if (item.getItemId() == R.id.listView) {
                mRecyclerView.setAdapter(simpleAdapter);
                mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
                //网格
            } else if (item.getItemId() == R.id.gridView) {
                mRecyclerView.setAdapter(simpleAdapter);
                mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));
                //瀑布流
            } else if (item.getItemId() == R.id.horizontal) {
                mRecyclerView.setAdapter(simpleAdapter);
                mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.HORIZONTAL));
                //横向滑动
            } else if (item.getItemId() == R.id.staggeredView) {
                mRecyclerView.setAdapter(simpleStaggeredAdapter);
                mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.VERTICAL));
                //添加数据
            } else if (item.getItemId() == R.id.add) {
                simpleAdapter.add(1);
                //减少数据
            } else if (item.getItemId() == R.id.delete) {
                simpleAdapter.delete(1);
            }
            return super.onOptionsItemSelected(item);
        }
    }
    
    

    效果如下:

    QQ图片20180621000226.png QQ图片20180621000233.png

    组合使用:

    (支持下拉刷新与自动加载,支持多布局与多数据源)

    通过一个adaper 进行实现,使用者只需传入布局id与数据源即可,使用简单方便,不用重复写adapter.

    在xml 在使用

     <cashierdesk.xkeshi.com.simple.x_view.recyclerview.XRecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    

    自定义 Adapter

    
    /**
     * 说明:RecyclerView 包裹Adapter
     * 杨阳:360621904 2018/5/30
     */
    @SuppressWarnings({"unchecked", "unused"})
    public abstract class WrapperAdapter extends RecyclerView.Adapter<WrapperViewHolder> {
        private IWrapperAdapterListener.OnItemClick mOnItemClick;
        private IWrapperAdapterListener.OnItemLongClick mOnItemLongClick;
        private Map<ItemType, List> mTypeList;
        private LayoutInflater inflater;
        private MyListenerImp myListenerImp;
        private RecyclerView.ViewHolder holder;
        private RecyclerView mRecyclerView;
        /**
         * item 的UI 存储需要跨列的类型(目前是加载类型)
         */
        private List<Integer> mItemTypeData;
    
        @SuppressWarnings("WeakerAccess")
        public WrapperAdapter(@NonNull Context context) {
            mTypeList = new LinkedHashMap<>();
            this.inflater = LayoutInflater.from(context);
            myListenerImp = new MyListenerImp();
            mItemTypeData = new ArrayList<>();
        }
    
        /**
         * 添加单布局holder
         *
         * @param LayoutId 布局Id
         * @param data     数据源
         */
        public void addHolder(int LayoutId, @NonNull List data) {
            mTypeList.put(new ItemType(LayoutId), data);
        }
    
        /**
         * 添加多布局holder,实体对象必须实现 {@link IWrapperAdapterMoreType}这个接口
         *
         * @param data 数据源
         */
        public void addMoreHolder(@NonNull List<IWrapperAdapterMoreType> data) {
            mTypeList.put(new ItemType(IWrapperAdapterMoreType.class.hashCode()), data);
        }
    
        public void addFloorLoadingHolder(int layoutId, @NonNull List<IWrapperAdapterFloorType> data,
                                          IWrapperAdapterListener.OnLoadingFloorItemShowCallback onLoadingFloorItemShowCallback) {
            mTypeList.put(new ItemTypeTwo(layoutId, onLoadingFloorItemShowCallback), data);
            mItemTypeData.add(layoutId);
        }
    
    
        /**
         * 设置item 的数据
         *
         * @param holder item 对应的Holder
         * @param object item 对应的数据对象
         */
        public abstract void setItemData(WrapperViewHolder holder, Object object);
    
        public void setOnItemClick(IWrapperAdapterListener.OnItemClick onItemLick) {
            mOnItemClick = onItemLick;
        }
    
        public void setOnItemLongClick(IWrapperAdapterListener.OnItemLongClick onItemLongClick) {
            mOnItemLongClick = onItemLongClick;
        }
    
        @Override
        public WrapperViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new WrapperViewHolder(inflater.inflate(viewType, parent, false), viewType);
        }
    
        @Override
        public void onBindViewHolder(final WrapperViewHolder holder, final int position) {
            setItemData(holder, getValue(position));
            Object object = getValue(position);
            //把holder,position,data 添加到view tag 中
            holder.itemView.setTag(R.id.tag_key_holder, holder);
            holder.itemView.setTag(R.id.tag_key_position, holder.getLayoutPosition());
            holder.itemView.setTag(R.id.tag_key_data, object);
            if (mOnItemClick != null && !(object instanceof IWrapperAdapterFloorType))
                holder.itemView.setOnClickListener(myListenerImp);
            if (mOnItemLongClick != null)
                holder.itemView.setOnLongClickListener(myListenerImp);
            if (mOnItemClick != null || mOnItemLongClick != null)
                holder.setItemBackground();
            //判断是否是加载的itemView
            if (object instanceof IWrapperAdapterFloorType) {
                ItemTypeTwo typeTwo = (ItemTypeTwo) getKey(position);
                assert typeTwo != null;
                if (typeTwo.mOnLoadingFloorItemShowCallback != null)
                    typeTwo.mOnLoadingFloorItemShowCallback.floorItemShowCallback(holder.itemView, holder, holder.getLayoutPosition(), object);
            }
        }
    
        @Override
        public int getItemCount() {
            return getSumCount();
        }
    
        @Override
        public int getItemViewType(int position) {
            return getMyItemViewType(position);
        }
    
        @Override
        public void onViewAttachedToWindow(WrapperViewHolder holder) {
            super.onViewAttachedToWindow(holder);
            // 处理StaggeredGridLayoutManager,设置充满整行
            ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
            if (null != layoutParams && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
                if (mItemTypeData.contains(mRecyclerView.getAdapter().getItemViewType(holder.getLayoutPosition())))
                    ((StaggeredGridLayoutManager.LayoutParams) layoutParams).setFullSpan(true);
            }
        }
    
    
        @Override
        public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            mRecyclerView = recyclerView;
            // 处理GridLayoutManager,设置充满整行
            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
            if (layoutManager instanceof GridLayoutManager) {
                final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
                gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        if (mItemTypeData.contains(mRecyclerView.getAdapter().getItemViewType(position))) {
                            return gridLayoutManager.getSpanCount();
                        }
                        return 1;
                    }
                });
            }
        }
    
        /**
         * 事件回调的处理
         */
        class MyListenerImp implements View.OnClickListener, View.OnLongClickListener {
            @Override
            public void onClick(View view) {
                mOnItemClick.click(view, (WrapperViewHolder) view.getTag(R.id.tag_key_holder), (int) view.getTag(R.id.tag_key_position), view.getTag(R.id.tag_key_data));
            }
    
            @Override
            public boolean onLongClick(View view) {
                mOnItemLongClick.longClick(view, (WrapperViewHolder) view.getTag(R.id.tag_key_holder), (int) view.getTag(R.id.tag_key_position), view.getTag(R.id.tag_key_data));
                return false;
            }
        }
    
        /**
         * 总条目数
         */
        private int getSumCount() {
            int sumCount = 0;
            for (Map.Entry entry : mTypeList.entrySet()) {
                if (entry.getValue() != null)
                    sumCount += ((List) entry.getValue()).size();
            }
            return sumCount;
        }
    
        /**
         * 条目UI 类型
         */
        private int getMyItemViewType(int position) {
            int count = 0;
            for (Map.Entry entry : mTypeList.entrySet()) {
                List list = (List) entry.getValue();
                //多布局
                if (list.get(0) instanceof IWrapperAdapterMoreType && ((count + list.size()) > position)) {
                    int moreCount = count;
                    for (int i = 0; i < list.size(); i++) {
                        if (moreCount == position) {
                            return ((IWrapperAdapterMoreType) list.get(i)).getItemViewId();
                        }
                        moreCount++;
                    }
                }
                //统一布局
                count += ((List) entry.getValue()).size();
                if (count > position) {
                    return ((ItemType) entry.getKey()).layoutId;
                }
            }
            return -1;
        }
    
        private ItemType getKey(int position) {
            int sumCount = 0;
            for (Map.Entry entry : mTypeList.entrySet()) {
                sumCount += ((List) entry.getValue()).size();
                if (sumCount > position) {
                    return (ItemType) entry.getKey();
                }
            }
            return null;
        }
    
        /**
         * 获取数据对象
         */
        private Object getValue(int position) {
            int sumCount = 0;
            for (Map.Entry entry : mTypeList.entrySet()) {
                for (int i = 0; i < ((List) entry.getValue()).size(); i++) {
                    if (sumCount == position) {
                        return ((List) entry.getValue()).get(i);
                    }
                    sumCount++;
                }
            }
            return null;
        }
    
        /**
         * 布局的类型
         */
        class ItemType {
            //布局的id
            int layoutId;
    
            ItemType(int layoutId) {
                this.layoutId = layoutId;
            }
        }
    
        class ItemTypeTwo extends ItemType {
            IWrapperAdapterListener.OnLoadingFloorItemShowCallback mOnLoadingFloorItemShowCallback;
    
            ItemTypeTwo(int layoutId, IWrapperAdapterListener.OnLoadingFloorItemShowCallback callback) {
                super(layoutId);
                this.mOnLoadingFloorItemShowCallback = callback;
            }
        }
    
    }
    
    

    Activity 中使用

    
    /**
     * RecyclerView  组合的封闭使用
     */
    public class TestXRecyclerViewActivity2 extends AppCompatActivity {
        XRecyclerView mRecyclerView;
        private List<String> mData;
        private List<String> mData1;
        private List<IWrapperAdapterMoreType> mData2;
        WrapperAdapter adapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test_xrecyclerview);
            mRecyclerView = findViewById(R.id.recyclerView);
            mData = new ArrayList<>();
            mData1 = new ArrayList<>();
            mData2 = new ArrayList<>();
    
            addData();
            adapter = new WrapperAdapter(TestXRecyclerViewActivity2.this) {
                @Override
                public void setItemData(WrapperViewHolder holder, Object object) {
                    setHolderData(holder, object);
                }
            };
    
            //设置数据,与布局id
            adapter.addHolder(R.layout.item_more_one, mData);
            adapter.addHolder(R.layout.item_more_two, mData);
            adapter.addHolder(R.layout.item_more_three, mData);
            adapter.addHolder(R.layout.item_more_one, mData1);
            adapter.addMoreHolder(mData2);
    
            //设置布局,动画、adapter
    //        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
            GridLayoutManager linearLayoutManager = new GridLayoutManager(this, 2, StaggeredGridLayoutManager.VERTICAL, false);
    //        StaggeredGridLayoutManager linearLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
            mRecyclerView.setLayoutManager(linearLayoutManager);
            mRecyclerView.setItemAnimator(new DefaultItemAnimator());
            mRecyclerView.setAdapter(adapter);
    
            //添加线
            VerticalDividerItemDecoration decoration = new VerticalDividerItemDecoration.Builder(this)
                    .colorResId(R.color.colorGreen)
                    .sizeResId(R.dimen.db_size)
                    .build();
            mRecyclerView.addItemDecoration(decoration);
            //添加线
            HorizontalDividerItemDecoration decorationH = new HorizontalDividerItemDecoration.Builder(this)
                    .colorResId(R.color.colorGreen)
                    .sizeResId(R.dimen.db_size)
                    .showLastDivider()
                    .build();
            mRecyclerView.addItemDecoration(decorationH);
            //设置事件与回调
            setListener();
    
        }
    
        int count;
    
        /**
         * 设置事件与回调
         */
        private void setListener() {
            /**
             * 设置点击事件
             */
            adapter.setOnItemClick(new IWrapperAdapterListener.OnItemClick() {
                @Override
                public void click(View view, WrapperViewHolder holder, int position, Object data) {
                    if (data instanceof String) {
                        String str = (String) data;
                        Toast.makeText(TestXRecyclerViewActivity2.this, "position:" + str + "--" + position, Toast.LENGTH_SHORT).show();
                    }
    
                    if (data instanceof MyWrapperAdapterMoreType) {
                        MyWrapperAdapterMoreType data1 = (MyWrapperAdapterMoreType) data;
                        Toast.makeText(TestXRecyclerViewActivity2.this, "position:" + data1.str + "--" + position, Toast.LENGTH_SHORT).show();
                    }
                }
            });
            /**
             * 刷新的回调
             */
            mRecyclerView.setRefreshListener(new IXRecyclerViewBiz.RefreshListener() {
                @Override
                public void onRefreshListener() {
                    mData.clear();
                    mData.add("new");
                    mData2.add(new MyWrapperAdapterMoreType(2, "新22"));
                    adapter.notifyDataSetChanged();
    
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mRecyclerView.stopRefreshing();
                            count = 0;
    //                        mRecyclerView.finishLoading();
                        }
                    }, 1000);
                }
            });
            /**
             * 加载更多回调
             */
            mRecyclerView.setLoadingListener(new IXRecyclerViewBiz.LoadingListener() {
                @Override
                public void onLoadingListener() {
                    Log.e("BBB", "加载的回调");
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mData2.add(new MyWrapperAdapterMoreType(1, "加载新" + count));
                            mData2.add(new MyWrapperAdapterMoreType(1, "加载新" + count));
                            mData2.add(new MyWrapperAdapterMoreType(2, "加载新" + count));
                            mData2.add(new MyWrapperAdapterMoreType(1, "加载新" + count));
                            mData2.add(new MyWrapperAdapterMoreType(3, "加载新" + count));
                            mData2.add(new MyWrapperAdapterMoreType(1, "加载新" + count));
                            adapter.notifyDataSetChanged();
                            mRecyclerView.stopRefreshing();
                            count++;
                            if (count == 4) {
                                mRecyclerView.finishLoading();
    
                            }
                        }
                    }, 1000);
                }
            });
    
        }
    
        /**
         * 设置UI 数据
         */
        private void setHolderData(WrapperViewHolder holder, Object object) {
            if (object instanceof String && R.layout.item_more_one == holder.getLayoutId()) {
                String str = (String) object;
                holder.setText(R.id.textView, str);
    
            } else if (object instanceof MyWrapperAdapterMoreType) {
                MyWrapperAdapterMoreType data = (MyWrapperAdapterMoreType) object;
                if (R.layout.item_more_one == holder.getLayoutId()) {
                    holder.setText(R.id.textView, data.str + "");
                } else if (R.layout.item_more_two == holder.getLayoutId()) {
                    holder.setText(R.id.textView1, data.str + "");
                    holder.setText(R.id.textView2, data.str + "");
                } else if (R.layout.item_more_three == holder.getLayoutId()) {
                    holder.setText(R.id.three_1, data.str + "");
                    holder.setText(R.id.three_2, data.str + "");
                    holder.setText(R.id.three_3, data.str + "");
                }
            } else if (object instanceof String && R.layout.item_more_two == holder.getLayoutId()) {
                String str = (String) object;
                holder.setText(R.id.textView1, str);
                holder.setText(R.id.textView2, str);
    
            } else if (object instanceof String && R.layout.item_more_three == holder.getLayoutId()) {
                String str = (String) object;
                holder.setText(R.id.three_1, str);
                holder.setText(R.id.three_2, str);
                holder.setText(R.id.three_3, str);
            }
    
        }
    
        /**
         * 添加数据
         */
        private void addData() {
            for (int i = 'A'; i <= 'C'; i++) {
                mData.add("" + (char) i);
            }
            mData1.add("1111111");
            mData1.add("1111111");
            mData1.add("1111111");
            mData1.add("1111111");
            mData1.add("1111111");
    
            mData2.add(new MyWrapperAdapterMoreType(3, "我是3"));
            mData2.add(new MyWrapperAdapterMoreType(2, "我是2"));
            mData2.add(new MyWrapperAdapterMoreType(2, "我是2"));
            mData2.add(new MyWrapperAdapterMoreType(2, "我是2"));
            mData2.add(new MyWrapperAdapterMoreType(2, "我是2"));
            mData2.add(new MyWrapperAdapterMoreType(2, "我是2"));
            mData2.add(new MyWrapperAdapterMoreType(1, "我是1"));
        }
    
        class MyWrapperAdapterMoreType implements IWrapperAdapterMoreType {
            int type;
            String str;
    
            MyWrapperAdapterMoreType(int type, String str) {
                this.type = type;
                this.str = str;
            }
    
            @Override
            public int getItemViewType() {
                return type;
            }
    
            @Override
            public int getItemViewId() {
                if (type == 1) {
                    return R.layout.item_more_one;
                } else if (type == 2) {
                    return R.layout.item_more_two;
                } else {
                    return R.layout.item_more_three;
                }
            }
        }
    
    }
    
    

    效果展示

    QQ图片20180621004110.png QQ图片20180621004115.png

    与DataBinding 结合使用:


    @ 时间不早了,下次继续更新
    

    源码地址:


    相关文章

      网友评论

      • ShawnChu:想想滑动时new了多少个onclicklistener
        一只笔:这个没有new呀 mOnItemClick,是外部设置过来的,只有一份实例

      本文标题:RecyclerView

      本文链接:https://www.haomeiwen.com/subject/ovcfyftx.html