RecyclerView基础知识

本文介绍了Android中RecyclerView的基本用法。需在build.gradle添加依赖,在activity_main.xml加入控件。定义适配器要重写三个方法,还说明了如何修改MainActivity.java代码。此外,讲解了实现横向滚动、瀑布流布局的方法,以及RecyclerView点击事件的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. RecyclerView的基本用法

    1. 谷歌把RecyclerView控件定义在了AndroidX当中,所以我们要在build.gradle中添加RecyclerView库的依赖。

      打开app/build.gradle文件,在depandencies闭包中添加如下内容:

      implementation 'androidx.recyclerview:recyclerview:1.1.0'
      

      ps:上诉代码版本号以后可能发生改变,需要根据提示进行同步

    2. 在activity_main.xml中加入RecyclerView控件:

      <?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="match_parent">
      
          <androidx.recyclerview.widget.RecyclerView
              android:id="@+id/recycler_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
      
      </LinearLayout>
      

      注意:由于RecyclerView不是内置在系统SDK当中,所以要把完整的包路径写出来

    3. 这里实现的是和ListView相同的效果,Fruit类和fruit_item.xml和ListView时的代码一样。

      代码参考另一篇文章:ListView基础知识

    4. 为RecyclerView定义一个适配器

      public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
      
          private List<Fruit> mFruitList;
      
          //此构造器用于把数据传进来
          public FruitAdapter(List<Fruit> fruitList) {
              mFruitList = fruitList;
          }
      
          static class ViewHolder extends RecyclerView.ViewHolder {
              ImageView fruitImage;
              TextView fruitName;
      
              //构造器中的view参数通常是RecyclerView子项的最外层布局
              public ViewHolder(@NonNull View itemView) {
                  super(itemView);
                  fruitImage = itemView.findViewById(R.id.fruit_image);
                  fruitName = itemView.findViewById(R.id.fruit_name);
              }
          }
      
          /**
           * 此方法用于创建ViewHolder实例
           * @param parent
           * @param viewType
           * @return
           */
          @NonNull
          @Override
          public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
              //把子项布局加载进来
              View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
              ViewHolder holder = new ViewHolder(view);
              return holder;
          }
      
          /**
           * 此方法用于对RecyclerView子项的数据进行赋值,在每一个子项被滚动到屏幕时执行
           * @param holder
           * @param position
           */
          @Override
          public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
              Fruit fruit = mFruitList.get(position);
              holder.fruitImage.setImageResource(fruit.getImageId());
              holder.fruitName.setText(fruit.getName());
          }
          
          @Override
          public int getItemCount() {
              return mFruitList.size();
          }
      
      }
      

      上诉代码中,首先定义了一个内部类ViewHolder,继承自RecyclerView.ViewHolder。ViewHolder构造器要传入RecyclerView子项最外层布局View参数,并在构造器中调用findViewById()方法获取布局中的实例。

      FruitAdapter的构造器用于将数据源传递进来。

      FruitAdapter继承自RecyclerView.Adapter,所以要重写三个方法:

      onCreateViewHolder()方法:用于创建ViewHolder实例,并把加载出来的布局传递到构造器中,然后把ViewHolder实例返回。

      onBindViewHolder()方法:用于对RecyclerView子项的数据进行赋值,在每一个子项被滚动到屏幕时执行。

      getItemCount()方法:返回RecyclerView子项的个数

    5. 修改MainActivity.java的onCreate()方法代码(初始化数据和定义List同ListView):

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          initFruits();
          RecyclerView recyclerView = findViewById(R.id.recycler_view);
          LinearLayoutManager layoutManager = new LinearLayoutManager(this);
          recyclerView.setLayoutManager(layoutManager);
          FruitAdapter adapter = new FruitAdapter(fruitList);
          recyclerView.setAdapter(adapter);
      }
      

      在上诉代码中首先获取到RecylerView实例,然后创建一个布局LinearLayoutManager(线性布局管理器)对象,并把它设置到RecyclerView当中,接着创建一个FruitAdapter对象,并通过构造器传递数据。最后调用RecyclerView的setAdapter()方法设置适配器即可。

  2. 实现横向滚动

    1. 首先要对fruit_item布局进行修改。因为目前这个布局里的元素是水平排列的,使用于纵向滚动。如果要实现横向滚动,需要把布局里的元素改成垂直排列。

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="100dp"
          android:layout_height="wrap_content"
          android:orientation="vertical">
      
          <ImageView
              android:id="@+id/fruit_image"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center_horizontal"/>
      
          <TextView
              android:id="@+id/fruit_name"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center_horizontal"
              android:layout_marginTop="10dp"/>
      
      </LinearLayout>
      
    2. 在MainActivity.java中的onCreate()方法修改代码,在创建布局管理器实例代码的后面加上下面一行代码:

      layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
      
  3. 实现瀑布流布局

    1. 修改fruit_item.xml中的代码:

      <?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="vertical"
          android:layout_margin="5dp">
      
          <ImageView
              android:id="@+id/fruit_image"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center_horizontal"/>
      
          <TextView
              android:id="@+id/fruit_name"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="left"
              android:layout_marginTop="10dp"/>
      
      </LinearLayout>
      
    2. 修改MainActivity中的代码:

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          initFruits();
          RecyclerView recyclerView = findViewById(R.id.recycler_view);
          StaggeredGridLayoutManager layoutManager = new
                  StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
          recyclerView.setLayoutManager(layoutManager);
          FruitAdapter adapter = new FruitAdapter(fruitList);
          recyclerView.setAdapter(adaptetar);
      }
      
      private void initFruits() {
          Fruit apple;
          for (int i = 0; i < 40; i++) {
          	//使用随机数生成不同长度的水果名,这样才能看出瀑布流布局的效果
              Random random = new Random();
              StringBuilder name = new StringBuilder();
              for (int j = 0; j < random.nextInt(20) + 1; j++) {
                  name.append("Apple");
              }
              apple = new Fruit(name.toString(), R.drawable.apple_pic);
              fruitList.add(apple);
          }
      
      }
      

      在上诉代码中,我们创建了一个StaggeredGridLayoutManager的实例,它的构造器接收两个参数,第一个用于指定布局的列数,第二个用于指定布局的排列方向

  4. RecyclerView的点击事件

    RecyclerView没有提供类似于setOnItemClickListener()这样注册监听器的方法,需要我们自己给item注册点击事件。

    修改FruitAdapter中的代码:

    static class ViewHolder extends RecyclerView.ViewHolder {
        View fruitView;
        ImageView fruitImage;
        TextView fruitName;
    
        //构造器中的view参数通常是RecyclerView子项的最外层布局
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            fruitView = itemView;
            fruitImage = itemView.findViewById(R.id.fruit_image);
            fruitName = itemView.findViewById(R.id.fruit_name);
        }
    }
    
    /**
     * 此方法用于创建ViewHolder实例
     * @param parent
     * @param viewType
     * @return
     */
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //把子项布局加载进来
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
        final ViewHolder holder = new ViewHolder(view);
        holder.fruitView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText(view.getContext(), "you click view " + fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        holder.fruitImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText(view.getContext(), "you click image " + fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }
    

    上诉代码中,在ViewHolder中添加了一个fruitView用来保存子项最外层布局实例,然后在onCreateViewHolder()方法中注册监听事件即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值