RecylerView的基本使用

在这里总结一下RecylerView的使用
注:这里主要是讲的如何去使用它,而没有很深度的去解析各种方法是怎样的,更没有去解析源码之类的。
方便以后复习查询
也加固自己的知识

这里先介绍一下RecylerView,这个是一个强大的滚动控件,可以代替之前的ListView,做很多ListView做不到的工作,比如横向的滚动等等,有更美的更强大的效果和体验。

  • RecyclerView的基本用法_线性布局(横向与纵向)
    首先RecyclerView作为一个新增的控件,为了让RecyclerView在所有的Android版本上都能使用,RecyclerView被定义在support库当中。所以在使用之前得添加相应的依赖库到项目中:
    打开build.gradle(Module:app)文件:
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation 'com.android.support:appcompat-v7:26.1.0'
        implementation 'com.android.support.constraint:constraint-layout:1.0.2'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.1'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
        implementation 'com.android.support:recyclerview-v7:26.1.0'
    }
    Android Studio 3.0 以后添加依赖不再是compile 而是implementation。注意,因为之前说了,这个依赖库是support库里面的,所以版本号要同你项目中的support库一致,也就是最后一行的版本号,要和第二行的版本号一致,否则要报错。写好依赖之后,再Sync Now一下(同步)。就可以使用Recycler View了。
    添加依赖之后就可以在布局里面添加控件了:
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    和listview一样,需要创建adapter来放数据。
    所以我们新建一个类来继承RecyclerView.Adapter
    public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
    }
    因为我们是要用自己定义的viewholder,所以在填泛型的时候就填我们自定义的,然后在红线(我复制的代码看不到红线,实际打完这段代码,在这个代码下面就会出现红线),这个时候需要导入方法和新建内部类,但是都不要怕,我们直接把鼠标移动到最后那个ViewHolder上面,然后按住alt+回车,系统就会让我们选择是否创建内部类,我们只要选择Create class 'ViewHolder'就可以了。
    public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
        public class ViewHolder {
        }
    }
    这样工具就帮我们创建好了,内部类,也就是我们自定义的viewholder(如果不知道viewholder是干嘛的,可以去学习一下listview,viewholder这个是用来缓存列表子view的)。内部类创建好了。但是红线还在,是我们继承了RecyclerView.Adapter但是还需要实现这个类的一些方法,也很简单,只需要把鼠标移动到红线上面然后alt+回车,然后选择Implement methods,就会弹出一个方框,让我们选择要实现的一些父类的方法,这里全选就可以了,都是必须要实现的。
    最后你会发现,BaseAdapter.ViewHolder下面还有红线,是因为我们创建的内部类还需要继承RecyclerView.Holder,不然系统就不会认为我们创建的这个内部类是一个holder,所以也很简单,鼠标移动到红线上面,然后alt+回车,Make 'ViewHolder' extend 'android.support7.widget.RecyclerView.ViewHolder'
    继承之后需要实现父类的方法,同理:
    public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return null;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
    
        }
    
        @Override
        public int getItemCount() {
            return 0;
        }
    
        public class ViewHolder extends RecyclerView.ViewHolder {
            public ViewHolder(View itemView) {
                super(itemView);
            }
        }
    }
    这样我们的一个adapter就创建好了,虽然代码有点多,感觉也很难记有这么多方法,但是实际上我们只需要打出第一行,其余的代码利用工具就可以帮我们完成,非常的方便。所以也非常的简单,之后我就不在这么详细的说去怎么操作了。我就直接说继承哪个类和实现父类的方法,就行了,不在累述如何去通过工具来做了。这篇文章建立在listview学习的基础之上,下面我就不再多解释什么是item,和怎么导入布局,为啥传入数据了。
    现在adapter有了,其实可以看到和listview的adapter是很相似的,接下来是创建我们的item布局,就简单的放一张图片和文字吧
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/iv_bi"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"/>
        <TextView
            android:id="@+id/tv_bi"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center" />
    </LinearLayout>
    然后在adapter中导入item布局,创建holder:
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.base_item,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }
    这里就和listview创建holder的方式不一样了,虽然方式不一样,但是作用是一样的,holder还是你所知道的那个holder。
    对了,holder里面还得添加控件,和listview一样:
    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView baseImageView;
        TextView baseTextView;
         ViewHolder(View itemView) {
            super(itemView);
            baseImageView = itemView.findViewById(R.id.iv_bi);
            baseTextView = itemView.findViewById(R.id.tv_bi);
        }
    }
    这里我也很好奇,如果你不是新手,你肯定会问,怎么没用强转呢?我也很好奇,我的是3.0的编译器,可能谷歌已经给我们优化了这个问题。(这里留个坑,好奇的小伙伴可以去查一下)
    然后创建我们的实体:
     
    public class BaseEntity {
        private int baseImage;
        private String baseText;
    
        public int getBaseImage() {
            return baseImage;
        }
    
        public void setBaseImage(int baseImage) {
            this.baseImage = baseImage;
        }
    
        public String getBaseText() {
            return baseText;
        }
    
        public void setBaseText(String baseText) {
            this.baseText = baseText;
        }
    }
    在adapter里面提供导入我们想要展示的数据的方法:
    private List<BaseEntity> baseEntityList;
    
    public BaseAdapter(List<BaseEntity> baseEntityList) {
        this.baseEntityList = baseEntityList;
    }
    和listview的adapter一样,我们在构建adapter的时候就可以把要展示的数据传进去。然后还需要小小的修改一下我们的adapter,我直接给出代码:
    public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
        private List<BaseEntity> baseEntityList;
    
        public BaseAdapter(List<BaseEntity> baseEntityList) {
            this.baseEntityList = baseEntityList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.base_item,parent,false);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            BaseEntity baseEntity = baseEntityList.get(position);
            holder.baseImageView.setImageResource(baseEntity.getBaseImage());
            holder.baseTextView.setText(baseEntity.getBaseText());
        }
    
        @Override
        public int getItemCount() {
            return baseEntityList.size();
        }
    
        static class ViewHolder extends RecyclerView.ViewHolder {
            ImageView baseImageView;
            TextView baseTextView;
             ViewHolder(View itemView) {
                super(itemView);
                baseImageView = itemView.findViewById(R.id.iv_bi);
                baseTextView = itemView.findViewById(R.id.tv_bi);
            }
        }
    然后就是使用了:
    private void initView() {
        mRecyclerView = findViewById(R.id.recycler_view);
        initDatas();//初始化BaseEntityList
    
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
        BaseAdapter baseAdapter = new BaseAdapter(baseEntityList);
        mRecyclerView.setAdapter(baseAdapter);
    }
    
    private void initDatas() {
        baseEntityList = new ArrayList<>();
        BaseEntity baseEntity;
        for (int i = 0;i<10;i++){
            baseEntity = new BaseEntity(R.mipmap.red_heart,i+"");
            baseEntityList.add(baseEntity);
        }
    }
    效果如下:

    在使用方面和listview不一样的是,多添加了一个layoutManager(这个布局管理作用非常大,之后的实现横向滚动就靠它)
    横向滚动:
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    mRecyclerView.setLayoutManager(layoutManager);
    BaseAdapter baseAdapter = new BaseAdapter(baseEntityList);
    mRecyclerView.setAdapter(baseAdapter);
    只需要加这么一句代码就搞定了,非常的方便。当然item布局要改为横向的,效果如下:

  • RecylcerView用法_网格布局:
    RecyclerView.LayoutManager是一个抽象类,而LinearLayoutManager(线性布局管理器)是一个实现类,一共有三个实现类。
    除了线性布局管理器以外还有以下两个实现类:
    GridLayoutManager 网格布局管理器
    StaggeredGridLayoutManager 瀑布流式布局管理器
    接下来,我们就使用以下网格布局管理器
    和我们之前使用线性布局管理器一样的用法,代码如下:
    //        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    //        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
            GridLayoutManager layoutManager = new GridLayoutManager(this,3);
            //新建一个网格布局管理器 后面的参数 第一个是context  第二个是网格有几列
            mRecyclerView.setLayoutManager(layoutManager);
            BaseAdapter baseAdapter = new BaseAdapter(baseEntityList);
            mRecyclerView.setAdapter(baseAdapter);
    只需要改动一行代码就完成了,下面是效果截图:

    网格布局和线性布局都非常的简单。
  • RecylcerView用法_瀑布流布局:
    首先先修改以下item布局里面的代码:
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:orientation="vertical"
        android:background="@color/background">
        <ImageView
            android:id="@+id/iv_bi"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"/>
        <TextView
            android:id="@+id/tv_bi"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    这里添加了背景颜色和间距(5dp),方便等会儿我们更直观的看出效果
    使用的代码部分:
    StaggeredGridLayoutManager layoutManager =
     new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
    //第一个参数是列数   第二个参数是方向
    也是只需要短短的一句就可以了,但是如果你这样运行的话,肯定是看不出效果的,为什么呢,因为你的每一个item数据都是一样的,所以显示不出效果,所以接下来稍微改变一下一些item的长度就可以了,代码如下:
    private void initDatas() {
        baseEntityList = new ArrayList<>();
        BaseEntity baseEntity;
        for (int i = 0;i<30;i++){
            baseEntity = new BaseEntity(R.mipmap.red_heart,i+getRandomLengthName("_hello_world"));
            baseEntityList.add(baseEntity);
        }
    }
    
    private String getRandomLengthName(String name){
        Random random = new Random();
        int length = random.nextInt(20) + 1;
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ;i<length;i++){
            builder.append(name);
        }
        return builder.toString();
    }
    本来文字部分只有  i  ,但是我在i的后面加了随机个数的“_hello_world”,这样就保证了每个item 的长度都不一样了,然后我们运行一下看一下效果:

    这样效果就出来了。
  • RecyclerView点击事件的添加:
    各种效果都是有了,但是如果不能互动是不是总感觉缺少了什么,接下来我们加上点击事件,这样就比较舒服了。
    接下来我们改动一下adapter,我直接上代码:
    public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
        private List<BaseEntity> baseEntityList;
    
        public BaseAdapter(List<BaseEntity> baseEntityList) {
            this.baseEntityList = baseEntityList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.base_item,parent,false);
            final ViewHolder holder = new ViewHolder(view);
            holder.baseView.setOnClickListener(new View.OnClickListener(){//给item添加监听
                @Override
                public void onClick(View view) {
                    int position = holder.getAdapterPosition();
                    Toast.makeText(view.getContext(), "你点击了 "+position, Toast.LENGTH_SHORT).show();
                }
            });
    
            holder.baseImageView.setOnClickListener(new View.OnClickListener() {//给item里面的图片添加监听
                @Override
                public void onClick(View view) {
                    int position = holder.getAdapterPosition();
                    Toast.makeText(view.getContext(), "你点击了 "+position+" 的图片", Toast.LENGTH_SHORT).show();
                }
            });
            return holder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            BaseEntity baseEntity = baseEntityList.get(position);
            holder.baseImageView.setImageResource(baseEntity.getBaseImage());
            holder.baseTextView.setText(baseEntity.getBaseText());
        }
    
        @Override
        public int getItemCount() {
            return baseEntityList.size();
        }
    
        static class ViewHolder extends RecyclerView.ViewHolder {
            View baseView;
            ImageView baseImageView;
            TextView baseTextView;
             ViewHolder(View itemView) {
                super(itemView);
                baseView = itemView;
                baseImageView = itemView.findViewById(R.id.iv_bi);
                baseTextView = itemView.findViewById(R.id.tv_bi);
            }
        }
    }
    红色的字体就是改动的地方,先看ViewHolder这儿,给ViewHolder这儿多添加了一个View,然后给View赋值就是当前的itemView,目的是为了给整个item添加监听。
    然后再看onCreateViewHolder这个方法这儿,这里是添加监听的地方,你看了这个地方之后就知道为什么要在holder里面多加一个view了。
    而且你可以给item布局里面的所有控件添加监听,非常的方便,也非常的人性化。下面我们看下效果:

    RecyclerView的基本用法就到这儿了,完成一般的任务是没有问题了,之后我会继续更新更多的更高级的用法。
    第一次发博客,主要是用的自己的口吻来描述自己学到的东西。
    如果有什么看不懂的方面欢迎大家留言。
    这里基本上就讲了一下用法,关于更深层的各种谈论我这里就不能顾及到了。大家有兴趣可以去看看一些大牛写的文章。
    文中部分代码引用于《第一行代码》郭霖
    这里我给出项目的git克隆地址:https://gitee.com/MrWmago/RecyclerViewSummary.git
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值