美文网首页
RecyclerView总结

RecyclerView总结

作者: 我就是杨过 | 来源:发表于2018-06-17 14:48 被阅读0次

    RecyclerView的用处

    • RecyclerView是support.v7包中的控件,可以说是ListView和GridView的增强升级版。

    RecyclerView的优点

    • 为什么要使用recycle view

    简单使用recycle view

    添加依赖库

    implementation 'com.android.support:recyclerview-v7:27.1.1'
    

    在布局文件中添加组件

    <android.support.v7.widget.RecyclerView
          android:layout_width="match_parent"
          android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
    

    编写每个item的布局

    • 就是写recycle view每个单元的布局详情
    • 一个recycle view可以加载多中布局文件,根据位置和类型加载不同的布局 后面详细总结

    在activity或者Fragment中获取recycle view对象并且进行设置

    • 代码如下
     RecycleView recyclerView = findViewById(R.id.recycler_view);
    //设置LayoutManager为LinearLayoutManager
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    //设置Adapter
    recyclerView.setAdapter(new GeneralAdapter(this,datas));
    
    • RecyclerView中默认带有三个布局管理器:LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager,这三种布局管理器都支持横向和纵向排列以及反向滑动。

    编写adapter

    public class GeneralAdapter extends RecyclerView.Adapter<GeneralAdapter.MyViewHolder> {
        //当前上下文对象
        Context context;
        //RecyclerView填充Item数据的List对象
        List<String> datas;
    //构造函数 自己定义看需要传递什么参数 这里传递的是上下文的对象和数据
        public GeneralAdapter(Context context,List<String> datas){
            this.context = context;
            this.datas = datas;
        }
    
        //创建ViewHolder
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            //引入item布局并且实例化为对象
            View v = View.inflate(context, R.layout.item_recycler,null);
            //返回MyViewHolder的对象 这是自己创建的继承RecyclerView.ViewHolder的 类
            return new MyViewHolder(v);
        }
    
        //绑定数据
        // 通过调用布局里面的view对象进行数据方面的绑定
        @Override
        public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
            holder.textView.setText(datas.get(position));
        }
    
        //告诉系统item的数量
        @Override
        public int getItemCount() {
            return datas.size();
        }
    
        //继承RecyclerView.ViewHolder抽象类的自定义ViewHolder
        class MyViewHolder extends RecyclerView.ViewHolder{
            TextView textView;
    
            public MyViewHolder(View itemView) {
                super(itemView);
                //通过每个itemView引入自己布局中的每个子View
                textView = itemView.findViewById(R.id.text);
            }
        }
    }
    
    • RecyclerView的adapter需要继承RecyclerView.Adapter这个抽象类。后面是一个必须继承自RecyclerView.ViewHolder抽象类的ViewHolder的泛型约束,也就是GeneralAdapter.MyViewHolder这个内部类
    • 在RecyclerView.Adapter抽象类有三个必须实现的抽象方法:
    public abstract VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType);
    
    public abstract void onBindViewHolder(@NonNull VH holder, int position);
    
    public abstract int getItemCount();
    

    以上就是RecycleView的简单使用

    下面来说RecycleView的具体需求中需要掌握的地方

    布局管理器

    • RecyclerView自身带有三种默认的布局管理器:LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager。
      -LinearLayoutManager将项目排列在一维列表中。使用RecyclerView LinearLayoutManager提供了像旧版本的功能ListView。 GridLayoutManager将项目排列在二维网格中,如棋盘上的方格。使用RecyclerView with GridLayoutManager 提供了像旧版本的功能GridView StaggeredGridLayoutManager 将项目排列在一个二维网格中,每列与之前的一列略有偏移,就像美国国旗中的星星一样。
    LinearLayoutManager
    • LinearLayoutManager线性布局管理器。布局管理器默认使用垂直排列布局,而需要水平排列布局的话则可以通过LinearLayoutManager对象的setOrientation方法设置。,此方法接收int类型的值,分别为RecyclerView中的两个Int常量: LinearLayout.HORIZONTAL 和 LinearLayout.VERTICAL;
    • 设置布局方向的时候 也可以通过构造函数进行 。第三个参数一般传false,它的用途是当为true时数据和滑动都是反向的。(TODO这个地方需要体验下真实效果)
    public LinearLayoutManager(Context context, @RecyclerView.Orientation int orientation,
    boolean reverseLayout)
    
    GridLayoutManager
    • 网格布局管理器顾名思义 item根据网格方式进行排列。跟线性布局管理器一样,也支持通过setOrientation()或者构造方法来设置Item的排列方向。
    • 设置网格的行(对应着水平布局)或者列(对应着垂直布局) recyclerView.setLayoutManager(new GridLayoutManager(this,3)); 第二个参数就是行或者列的数目

    StaggeredGridLayoutManager

    • 瀑布流布局管理器 可以实现酷炫的瀑布流效果。它最常用的构造函数就一个StaggeredGridLayoutManager(int spanCount, int orientation),spanCount代表每行或每列的Item个数,orientation代表列表的方向,竖直或者水平。
    • 需要注意的地方 要实现瀑布流效果(仅讨论竖直方向的瀑布流样式),每一个Item的高度要有所差别,如果所有的item的高度相同,就和网格样式是一样的展示效果。因此实现瀑布流效果开发者需要根据位置加载不同的item布局界面。这样就可以实现了。参考下面的总结。

    item点击事件

    有两种处理方式分别是

    • 在Adapter里面直接对控件做点击事件
    @Override
        public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
            holder.textView.setText(datas.get(position));
            holder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //do something
                }
            });
        }
    
    • 写接口,在Activity或Fragment上实现接口中定义的方法
    • 定义回调接口
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }
    public interface OnItemLongClickListener {
        boolean onItemLongClick(View view, int position);
    }
    
    • adapter 中进行设置
    public class GeneralAdapter extends RecyclerView.Adapter<GeneralAdapter.MyViewHolder> {
        //当前上下文对象
        Context context;
        //RecyclerView填充Item数据的List对象
        List<String> datas;
    
        public GeneralAdapter(Context context,List<String> datas){
            this.context = context;
            this.datas = datas;
        }
    
        private OnItemClickListener onItemClickListener;
        private OnItemLongClickListener onItemLongClickListener;
        public void setOnItemClickListener(OnItemClickListener listener) {
            this.onItemClickListener = listener;
        }
    
        public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
            this.onItemLongClickListener = onItemLongClickListener;
        }
        //绑定数据
        @Override
        public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
            holder.textView.setText(datas.get(position));
            //通过接口回调响应点击事件
            holder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if(onItemClickListener != null){
                        onItemClickListener.onItemClick(view,position);
                    }
    
                }
            });
            //通过接口回调响应长按事件
            holder.textView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    if(onItemLongClickListener != null){
                        return onItemLongClickListener.onItemLongClick(view,position);
                    }
                    return false;
                }
            });
        }
    
    • 在activity中的代码
    //点击事件
            adapter.setOnItemClickListener(new GeneralAdapter.OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    Toast.makeText(GeneralActivity.this,datas.get(position)+"被点击了",
                            Toast.LENGTH_SHORT).show();
                }
            });
            //长按事件
            adapter.setOnItemLongClickListener(new GeneralAdapter.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(View view, int position) {
                    Toast.makeText(GeneralActivity.this,datas.get(position)+"被长按了",
                            Toast.LENGTH_SHORT).show();
                    return true;
                }
            });
    

    根据Recycleview的位置加载不同的布局

    @Override
        public int getItemViewType(int position) {     
            if(position %2 == 0){
                return 0;
            }else{
                return 2;
            }
        }
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View v;
            if(viewType == 0){
                v = View.inflate(context,R.layout.item_recycler,null);
            }else{
                v = View.inflate(context,R.layout.item2_recycler,null);
            }
    
            return new MyViewHolder(v);
        }
    
    • getItemViewType() 这个方法顾名思义是用来设置每个item的类型的,传进来的参数是int类型的位置参数。返回类型同样是int类型。这个返回值是自定义的,自己知道什么样的数字代表什么样的类型就可以了。
    • onCreateViewHolder()方法中传进来的参数就有viewType这个参数,然后根据这个参数进行不同的布局加载。

    点击item在被点击的item上面显示一个对话框一样的东西

    • 解决方案参考我的另外一篇文章链接

    还有很多要掌握的技巧没有总结出来 以后会一一补充的。先列举如下

    • 滑动动画
    • 添加头和尾巴
    • 上拉加载和下拉刷新
    • item间隔线,
    • 删除某个item,删除动画

    相关文章

      网友评论

          本文标题:RecyclerView总结

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