当前位置:   article > 正文

【Android入门到项目实战--3.5】—— 滚动控件RecyclerView的使用_recyclerview 滚动条

recyclerview 滚动条

目录

序言

一、RecyclerView的基本用法

 二、实现横向滚动和瀑布流布局

1、横向滚动

2、瀑布流布局

二、RecyclerView的点击事件


本篇文章主要讲解滚动控件RecyclerView的使用,包括基本使用和点击事件。

序言

        上篇文章主要讲解了ListView的用法,但是ListView并不是完全没有缺点的,如:不使用技巧优化,性能会很差;还有,扩展性也不够好,它只能实现数据纵向滚动的效果。

        为此RecyclerView不仅可以轻松实现和ListView同样的效果,还优化了ListView中存在的各种不足,且Android官方也更加推荐使用RecyclerView。

一、RecyclerView的基本用法

        RecyclerView属于新增控件,被定义在了support库中,想要使用,需要在项目的build.gradle中添加相应的依赖库。

首先新建RecyclerView项目,并创建好活动。

打开app/build.gradle,在dependencies闭包中添加如下代码:

implementation 'androidx.recyclerview:recyclerview:1.2.1'

添加完后点击Sync Now来同步。

然后修改activity_main.xml中的代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <androidx.recyclerview.widget.RecyclerView
  6. android:id="@+id/recycler_view"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"/>
  9. </LinearLayout>

接下来实现与前一文章的ListView相同的效果,直接将Image类、item.xml、image3.png复制过来(如有需要参考代码,请参考上一文章,链接:https://blog.csdn.net/Tir_zhang/article/details/129718771?spm=1001.2014.3001.5501)。

接下来为RecyclerView准备一个适配器,新建一个adapter类,代码如下:

        代码稍微有点长,但是比ListView适配器更好理解。

        首先定义一个内部类ViewHolder,继承自RecyclerView.ViewHolder,然后在构造函数中传入View参数,这个参数通常是RecyclerView子项的最外层布局,然后可以通过findViewById()方法来获取到布局中的ImageView和TextView实例了。

        adapter的构造函数,用于把展示的数据源传进来。

        adapter继承自RecyclerView.Adapter,需要重写onCreateViewHolder()、onBindViewHolder()、getItemCount()这3个方法。onCreateViewHolder()方法是用于创建ViewHolder实例的onBindViewHolder()方法用于对RecyclerView子项数据赋值,会在子项被滚动到屏幕内的时候执行,通过position参数获取到当前项的实例,再设置到ImageView和TextView当中;getItemCount()方法用于告诉RecyclerView一共有多少子项,直接返回长度。

  1. public class adapter extends RecyclerView.Adapter<adapter.ViewHolder> {
  2. private List<Image> list;
  3. static class ViewHolder extends RecyclerView.ViewHolder{
  4. ImageView image;
  5. TextView name;
  6. public ViewHolder(View view){
  7. super(view);
  8. image = (ImageView) view.findViewById(R.id.image);
  9. name = (TextView) view.findViewById(R.id.name);
  10. }
  11. }
  12. public adapter(List<Image> list2){
  13. list = list2;
  14. }
  15. public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
  16. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
  17. ViewHolder holder = new ViewHolder(view);
  18. return holder;
  19. }
  20. public void onBindViewHolder(ViewHolder holder,int position){
  21. Image image = list.get(position);
  22. holder.image.setImageResource(image.getImageId());
  23. holder.name.setText(image.getName());
  24. }
  25. public int getItemCount(){
  26. return list.size();
  27. }
  28. }

准备好适配器,可以使用RecyclerView了,修改MainActivity中的代码,如下:

        下面的LayoutManager用于指定RecyclerView的布局方式,这里使用的LinearLayoutManager是线性布局的意思。

  1. public class MainActivity extends AppCompatActivity {
  2. private List<Image> list = new ArrayList<>();
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. init();//初始化数据
  8. RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
  9. LinearLayoutManager layoutManager = new LinearLayoutManager(this);
  10. recyclerView.setLayoutManager(layoutManager);
  11. adapter ad = new adapter(list);
  12. recyclerView.setAdapter(ad);
  13. }
  14. private void init(){
  15. for(int i = 0; i < 2; i++){
  16. Image a = new Image("A",R.drawable.image3);
  17. list.add(a);
  18. Image b = new Image("B",R.drawable.image3);
  19. list.add(b);
  20. Image c = new Image("C",R.drawable.image3);
  21. list.add(c);
  22. Image d = new Image("D",R.drawable.image3);
  23. list.add(d);
  24. Image e = new Image("E",R.drawable.image3);
  25. list.add(e);
  26. }
  27. }
  28. }

效果如下:

 二、实现横向滚动和瀑布流布局

1、横向滚动

首先修改item.xml布局的代码,如下:

        目前此布局的元素都是水平排列,适用于纵向滚动的场景,如果横向滚动,应该改成垂直排列。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="100dp"
  5. android:layout_height="wrap_content">
  6. <ImageView
  7. android:id="@+id/image"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:layout_gravity="center_horizontal"/>
  11. <TextView
  12. android:id="@+id/name"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. android:layout_gravity="center_horizontal"
  16. android:layout_marginTop="10dp"/>
  17. </LinearLayout>

接下来修改MainActivity代码,如下:

 只加入了一行代码:   layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

默认是纵向排列,调用setOrientation()方法来设置布局排列方向。

  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_main);
  4. init();//初始化数据
  5. RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
  6. LinearLayoutManager layoutManager = new LinearLayoutManager(this);
  7. layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
  8. recyclerView.setLayoutManager(layoutManager);
  9. adapter ad = new adapter(list);
  10. recyclerView.setAdapter(ad);
  11. }

效果如下:

 

2、瀑布流布局

    除LinearLayoutManager之外,还有GridLayoutManager和StaggeredGridLayoutManager这两种内置的布局方式。GridLayoutManager用来实现网格布局,StaggeredGridLayoutManager用来实现瀑布流布局,下面实现瀑布流布局。

修改item.xml代码,如下:

        这里只修改了两部分,首先将LinearLayout的宽度由100dp改成了match_parent,因为瀑布流的宽度应该是根据布局的列数自动适配,而不是固定值;另外,TextView的对齐方式改成了左对齐。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content"
  6. android:layout_margin="5dp">
  7. <ImageView
  8. android:id="@+id/image"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:layout_gravity="center_horizontal"/>
  12. <TextView
  13. android:id="@+id/name"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"
  16. android:layout_gravity="left"
  17. android:layout_marginTop="10dp"/>
  18. </LinearLayout>

接着修改MainActivity.java代码,如下:

        首先,再onCreate方法中,创建StaggeredGridLayoutManager实例,构造函数接收两个参数,第一个参数用于指定布局的列数,第二个参数用于指定布局的排列方向

  1. public class MainActivity extends AppCompatActivity {
  2. private List<Image> list = new ArrayList<>();
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. init();//初始化数据
  8. RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
  9. StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
  10. recyclerView.setLayoutManager(layoutManager);
  11. adapter ad = new adapter(list);
  12. recyclerView.setAdapter(ad);
  13. }
  14. private void init(){
  15. for(int i = 0; i < 5; i++){
  16. Image a = new Image("AAAAAAAAAAAAAAAAAA",R.drawable.image3);
  17. list.add(a);
  18. Image b = new Image("BBBBBB",R.drawable.image3);
  19. list.add(b);
  20. Image c = new Image("CCCCCCCCCCC",R.drawable.image3);
  21. list.add(c);
  22. Image d = new Image("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",R.drawable.image3);
  23. list.add(d);
  24. Image e = new Image("EEE",R.drawable.image3);
  25. list.add(e);
  26. }
  27. }
  28. }

效果如下:

 

二、RecyclerView的点击事件

        RecyclerView的点击事件需要我们自己给子项具体的View去注册点击事件,比ListView实现要复杂一点。

        那么为什么RecyclerView设计的更复杂一点?假设以下场景:如果想要点击子项里具体的按钮,如何做?ListView的setOnItemClickListener()方法注册的是子项的点击事件,实现这个功能比较麻烦,为此,RecyclerView直接去除了子项点击事件的监听器,所有的点击事件都有具体的View去注册。

接下来尝试实现。

修改adapter中的代码,如下:

        下面加粗部分为新增代码。

        imageView变量用来保存子项最外层布局的实例,然后在onCreateViewHolder()方法中注册点击事件,这里为ImageView注册了点击事件。

public class adapter extends RecyclerView.Adapter<adapter.ViewHolder> {
    private List<Image> list;
    static class ViewHolder extends RecyclerView.ViewHolder{
        View imageView;
        ImageView image;
        TextView name;
        public ViewHolder(View view){
            super(view);
            imageView = view;
            image = (ImageView) view.findViewById(R.id.image);
            name = (TextView) view.findViewById(R.id.name);
        }
    }

    public adapter(List<Image> list2){
        list = list2;
    }

    public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
        final ViewHolder holder = new ViewHolder(view);
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = holder.getAbsoluteAdapterPosition();
                Image image = list.get(position);
                Toast.makeText(view.getContext(), "你点击了"+image.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }

...

}

      效果如下:

 


希望本文章对你有帮助,如果你对Android开发感兴趣,请持续关注本专栏,帮助你从入门到项目实战,你将收获:Android基础开发、各种经典功能实现、项目实战、开发自己的APP、将APP上传应用商店、靠广告赚钱等等,持续更新ing......

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/538655
推荐阅读
相关标签
  

闽ICP备14008679号