欢迎回来Android入门教程的第八期,这一期开始学习RecyclerView的使用。在没有RecyclerView之前,若要实现列表或网格布局,通常会使用ListView和GridView,在RecyclerView出现后,就可以代替它们了。多样式列表、网格布局或是类似快手的流布局它都能实现,这些我都会在下几期教程中一一讲解。那么本期先来学习RecyclerView的列表布局吧。

上期传送门:#7 Android入门教程 – 滚动视图 – LovelyCat的小站 (lovelycatv.cn)

下期传送门:#9 Android入门教程 – RecyclerView(2) – LovelyCat的小站 (lovelycatv.cn)

那么首先需要有一个RecyclerView布局,然后在主类中获取到这个组件。接着新建一个类,这边我命名为RecyclerViewAdapter,让它继承RecyclerView.Adapter<RecyclerView.ViewHolder>。

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }
}

将光标移动到标红区域,按Alt+Enter导入所有必须方法后如上所示。

现在我们已经创建好了一个适配器,那么既然是列表,需要有列表项目来显示,所以我们需要外部创建适配器时给适配器传入一组数据来显示。这里我们使用最简单的ArrayList来演示。

    public Context mContext;
    public List<String> mDatas;

    public RecyclerViewAdapter(Context mContext, List<String> mDatas) {
        this.mContext = mContext;
        this.mDatas = mDatas;
    }

在适配器内加入两个变量和构造函数以便数据传输。这边还加入了Context,现在不介绍它,但在RecycleView中常用。

那么现在这个适配器还差最后一点,就是布局样式和一些代码了。下面我们来新建一个布局文件。

在项目结构中找到layout文件夹,右键 New Layout resource file,命名随意(不包括大写与数字开头)。下面我就随便写一个布局吧。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="12dp">
    <ImageView
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@mipmap/ic_launcher"/>
    <TextView
        android:id="@+id/reitem_tv"
        android:layout_marginStart="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is Title"
        android:textSize="18sp" 
        android:textColor="#000"
        android:layout_gravity="center"/>
</LinearLayout>

注意,在这个布局中,父组件LinearLayout的高度是wrap_content。那我们继续教程。

回到适配器,接下来我们需要创建一个ViewHolder。在适配器内写入一个新类,名为MainViewHolder(随意),继承RecyclerView.ViewHolder,并导入需要的方法。紧接着在里面声明一个变量为TextView类型,在MainViewHolder的构造方法内给它赋值。

信息
这里不能直接使用findViewById,因为没有指明一个具体的寻找范围,所以需要使用itemView下的此方法。也就是在这个View中寻找子组件,那么这个View就是我们刚才写好的布局。

    class MainViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        public MainViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.reitem_tv);
        }
    }

ViewHolder也创建好了,最后我们只需要将它们显示出来即可。现在我们开始改造最初创建的三个函数。

首先看onCreateViewHolder,在每一个ViewHolder创建时都会调用此方法,通过此方法用于指定一个列表项目的布局。我们使用LayoutInflater来获取到刚才写好的布局,并将View返回。如下所示:

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.reitem, parent, false);
        return new MainViewHolder(itemView);
    }

接着看到getItemCount,这个方法用于返回数据的个数,也就相当于是列表项目数量,我们只需要将mData的size传递给它就好。

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

最后来看onBindViewHolder,它可以让数据与ViewHolder绑定起来,也就是可以给每一个列表项目赋值,修改它们的布局。在每一个ViewHolder创建后,都会调用这个方法,并且传递position参数以标明本项是列表中的第几项,来具体看一看例程吧:

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        String item = mDatas.get(position);
        MainViewHolder mainViewHolder = (MainViewHolder) holder;
        mainViewHolder.textView.setText(item);
    }

由上述代码可知,本项该显示什么内容,取决于position的数值。并且将RecyclerView.ViewHolder强制转换成我们写好的ViewHolder,就可以实现布局修改的操作。

现在我们已经完成了一个适配器的创建,最后一步,就是将适配器挂载到我们的RecyclerView上,回到主类。

新建两个全局变量用于储存适配器和列表数据,在onCreate()中,新建适配器,Context传入this即可。然后再为RecyclerView指定一种显示方式。这里用线性布局的vertical模式。

public class MainActivity extends AppCompatActivity {
    public RecyclerViewAdapter recyclerViewAdapter;
    public List<String> rvItems = new ArrayList<>();
    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rvItems.add("这里是第一项");
        rvItems.add("这里是第二项");
        rvItems.add("这里是第三项");
        rvItems.add("这里是第四项");
        rvItems.add("这里是第五项");

        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        recyclerViewAdapter = new RecyclerViewAdapter(this, rvItems);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);

        recyclerView.setAdapter(recyclerViewAdapter);
    }
}

下面附上适配器的所有代码:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public Context mContext;
    public List<String> mDatas;

    public RecyclerViewAdapter(Context mContext, List<String> mDatas) {
        this.mContext = mContext;
        this.mDatas = mDatas;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.reitem, parent, false);
        return new MainViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        String item = mDatas.get(position);
        MainViewHolder mainViewHolder = (MainViewHolder) holder;
        mainViewHolder.textView.setText(item);
    }

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


    class MainViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        public MainViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.reitem_tv);
        }
    }
}

最后来看看效果吧。

那么本期教程就到此结束啦,RecyclerView对于新手来说,比较难理解它的工作流程,下面给出一张图,内容是我自己的理解,仅供参考。

1627978824 945tzli3aif Rl6p0c9o

0 条评论

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注