RecyclerView控件的基本使用(增强版的ListView)

ListView由于其强大的功能,在过去的Android开发当中可以说是贡献卓越,直到今天仍然还有不计其数的程序在继续使用着ListView。不过ListView并不是完全没有缺点的,比如说如果我们不使用一些技巧来提升它的运行效率,那么ListView的性能就会非常差。还有ListView的拓展性也不够好,它只能实现数据纵向滚动的效果,如果我们想实现横向滚动的话,ListView是做不到的。

为此,Android提供了一个更强大的滚动控件RecyclerView。它可以说是一个增强版的ListView,不仅可以轻松实现和ListView同样的效果,还优化了ListView中存在的各种不足之处。目前Android官方更加推荐使用RecyclerView,未来也会有更多的程序逐渐从ListView转向RecyclerView,所以,掌握RecyclerView控件的使用方法是很有必要的,下面我们一起来了解下RecyclerView的用法吧。

RecyclerView属于新增的控件,为了让RecyclerView可以在Android所有版本中都可以使用,Android团队将RecyclerView定义在了support库当中。因此,想要使用RecyclerView这个控件,首先需要在项目的build.gradle中添加相应的依赖库才行。

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

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

添加完了之后记得要点击一下Sync Now来进行同步。

activity_main.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="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

布局中代码很好理解,就引入了一个RecyclerView控件,指定了控件id,控件宽度,控件高度。

这里我们想要使用RecyclerView来实现和ListView相同的效果,因此就需要准备一份同样的水果图片。简单起见,我们就直接将ListView项目中的图片文件复制过来就可以了,另外Fruit类和fruit_item.xml也可以复制过来。这里我都贴上代码吧:

Fruit.java代码:

package com.example.administrator.activitydemo;

public class Fruit {

    private String name;

    private int imageId;

    public Fruit(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }

    public String getName() {
        return name;
    }

    public int getImageId() {
        return imageId;
    }
}

 

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">

    <ImageView
        android:id="@+id/iv_name"
        android:layout_width="40dp"
        android:layout_height="40dp" />

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp" />

</LinearLayout>

接下来需要为RecyclerView准备一个适配器,新建FruitAdapter类,让这个适配器继承自RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder。从java语法中我们也可以看出,ViewHolder类是我们在FruitAdapter类中定义的一个内部类。

FruitAdapter.java代码:

package com.example.administrator.activitydemo;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

    private List<Fruit> fruitList;

    public FruitAdapter(List<Fruit> fruitList) {
        this.fruitList = fruitList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fruit_item, viewGroup, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        Fruit fruit = fruitList.get(i);
        viewHolder.iv_name.setImageResource(fruit.getImageId());
        viewHolder.tv_name.setText("" + fruit.getName());
    }

    @Override
    public int getItemCount() {
        return fruitList.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView iv_name;
        TextView tv_name;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            iv_name = (ImageView) itemView.findViewById(R.id.iv_name);
            tv_name = (TextView) itemView.findViewById(R.id.tv_name);
        }
    }
    

}

虽然这段代码看上去好像有点长,但其实它比ListView的适配器更容易理解。这里我们首先定义了一个内部类ViewHolder,ViewHolder要继承自RecyclerView.ViewHolder。然后ViewHolder的构造函数中要传入一个View参数,这个参数通常就是RecyclerView子项的最外层布局,那么我们就可以通过findViewById()方法来获取到布局中的ImageView和TextView的实例了。

接着往下看,FruitAdapter中也有一个构造函数,这个方法用于把要展示的数据源传进来,并赋值给一个全局变量fruitList,我们后续的操作都将在这个数据源的基础上进行。

继续往下看,由于FruitAdapter是继承自RecyclerView.Adapter的,那么就必须重写以下3个方法了。

1.onCreateViewHolder(),这个函数是用于创建ViewHolder实例的,从它的返回值类型就可以看出,我们在这个函数中主要将fruit_item.xml布局加载到ViewHolder中,并将创建好的ViewHolder实例返回。

2.onBindViewHolder(),这个函数是用于对RecyclerView子项的数据进行赋值的,会在每个子项被滚动到屏幕内的时候执行,这里我们通过i参数得到当前项的Fruit实例,然后将数据设置到ImageView和TextView中即可。

3getItemCount(),这个函数是用于告诉RecyclerView一共有多少子项,这里直接返回数据源的长度就可以了。

适配器准备好了之后,我们就可以在MainActivity中使用RecyclerView控件了。

MainActivity.java代码:

package com.example.administrator.activitydemo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private String[] data = {"Apple", "Banana", "Orange", "Watermelon",
            "Pear", "Grape", "Pineapple", "Strawberry", "Cherry", "Mango",
            "Apple", "Banana", "Orange", "Watermelon",
            "Pear", "Grape", "Pineapple", "Strawberry", "Cherry", "Mango"
    };
    private int[] res = {R.drawable.apple, R.drawable.banana, R.drawable.orange, R.drawable.watermelon,
            R.drawable.pear, R.drawable.grape, R.drawable.pineapple, R.drawable.strawberry, R.drawable.cherry, R.drawable.mango,
            R.drawable.apple, R.drawable.banana, R.drawable.orange, R.drawable.watermelon,
            R.drawable.pear, R.drawable.grape, R.drawable.pineapple, R.drawable.strawberry, R.drawable.cherry, R.drawable.mango};
    private List<Fruit> fruitList;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();//初始化UI控件
        initData();//初始化数据
    }


    private void initView() {
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    }

    private void initData() {
        initFruits();//初始化水果数据
        LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(layoutManager);
        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }

    private void initFruits() {
        fruitList = new ArrayList<>();
        for (int i = 0; i < data.length; i++) {
            Fruit fruit = new Fruit(data[i], res[i]);
            fruitList.add(fruit);
        }
    }

}


可以看出,MainActivity.java中的代码与之前差不多,主要修改了initData()方法中以下几个地方:

1.添加了一个LinearLayoutManager(线性布局管理器)

2.为RecyclerView控件设置了布局管理器,参数传入上面的LinearLayoutManager(线性布局管理器)

3.实例化一个FruitAdapter适配器

4.为RecycerView设置适配器

效果图:

可以看出,我们使用RecyclerView实现了和ListView几乎一模一样的效果,虽说在代码方面并没有明显地减少,但是逻辑变得更加清晰了,如果你只是初次使用RecyclerView控件,可能暂时还不太能了解它的强大,记得我在初次学习它的时候,也并不能感受到它有多大优势,只是听到周遭的吹嘘,就尝试着了解了下这个控件,发现确实比ListView要好用一点,可能这就是知识的魅力吧,在不断探索中,得以成长,在收获经验的同时,增强主观的判断。

 

 

猜你喜欢

转载自blog.csdn.net/android_studying/article/details/86061280
今日推荐