安卓开发博客Android之ListViewRecyclerView

RecyclerView

2018-06-21  本文已影响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 结合使用:


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

源码地址:


上一篇下一篇

猜你喜欢

热点阅读