欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android应用开发--RecyclerView滚动控件

程序员文章站 2022-05-14 19:53:49
...

关键词:
Android手机应用开发、RecyclerView控件

开发环境:Windows 10 x64、Android studio2.2

实现功能:使用RecyclerView控件,实现一个可滚动的效果,并且控件中可滚动的每一项的内容和布局都可以*设计。

具体流程:导入工具包、在布局文件中使用、编写单元项布局、编写适配器、在后台将数据写入以在前台显示出来、为每一个单元项设计单击事件。

大致效果图,可上下滑动以显示其他内容
Android应用开发--RecyclerView滚动控件
项目文件RecyclerView滚动控件的使用可自行下载查看

1.导入工具包

首先,在Grande Scripts/build.gradle(Module:app)上双击打开app配置文件,在其中加上这个

compile 'com.android.support:recyclerview-v7:26.+'

其中26.+可以根据自己Android生成的SDK的版本号进行更改,比如
Android应用开发--RecyclerView滚动控件
添加完包的信息之后,单击Sync Now,如果各位的Android studio没有自动弹出那个选项,可以直接在这个位置选择
Android应用开发--RecyclerView滚动控件
较详细的流程可参照Android应用开发–LitePal操作数据库中的第一步

2.在布局中使用它

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

在书写这个控件的时候只需要写RecyclerView,Android studio就会自动弹出你需要的东西了,记住这个地方必须写完整这个东西,因为RecyclerView这个控件并不是内置于系统的SDK中的,所必须得把完整的路径写出来,也就是全限定名
Android应用开发--RecyclerView滚动控件

3.编写单元项的布局

首先在app/res/layout里面创建一个新的布局文件,文件名就叫做recyclerview_item
Android应用开发--RecyclerView滚动控件
创建伊始,会有这个属性,在这里我们把它删除掉,因为我们在这里需要的是从左往右的线性布局,而非从上往下的线性布局。

android:orientation="vertical"

然后我们自定义滚动控件中每一个单元项的布局
Android应用开发--RecyclerView滚动控件
这里需要注意的是划红线的部分,其他的布局文件这里基本都是match_parent属性,这里的wrap_content属性意味着,这个布局的高度等于它内容的总高度,也就是说这个布局的高度随着它内部内容的总高度在变化
因为我们写的这个布局是滚动控件中的其中一个单元项,所以它的高度不能是match_parent,而只能是wrap_content

4.编写适配器

适配器,简单的说就是接口转化,我们手机充电插头就可以说是一种适配器,它把220V-50Hz的电能转化为我们手机可以正常使用充电的电能;以及OTG转换头,给手机接一个USB接口,将USB口转化为我们手机的充电口。等等。

感兴趣的可以了解一下物理意义上的适配器,或者了解软件设计方面的设计模式-适配器模式。

接下来我们开始编写适配器,在编写适配器之前,我们需要一个类,来存储滚动控件中每一个单元项中所需要的数据。
例如
Android应用开发--RecyclerView滚动控件
我们先创建一个Dao的包,这里面存储所有的Java Bean,即一般情况下只含有成员变量及getter和setter方法的类。
较详细的创建流程以及小技巧可以参照Android应用开发–LitePal操作数据库中的第三部分

然后我们在Adapter包里面编写我们需要的适配器

// 此处的package自行根据自己的情况填写,或由Android studio自动生成
package ......;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.administrator.recyclerviewtest.Dao.RecyclerViewItem;
import com.example.administrator.recyclerviewtest.R;

import java.util.List;

/**
 * Created by Administrator on 2020/11/23.
 */

// 继承了一个RecyclerView.Adapter类,后面<>中的内容是一个限定
// 跟List<String>这个限定含义一样,便可以理解为这个List里面只能添加String对象
// 在这里做的限定为RecyclerViewAdapter类中的一个内部类,名字叫ViewHolder
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

	// 存储滚动控件中所有数据的对象
	// 该List中的每一个对象即为滚动控件中的每一个单元项
    private List<RecyclerViewItem> recyclerViewItemList;

    // 内部类,在这里面将单元项布局中的控件获取到后台代码中
    static class ViewHolder extends RecyclerView.ViewHolder {
        // 用来存储滚动控件中每一个单元项的布局文件中的各个控件
        // 即我们刚刚编写的recyclerview_item.layout布局中的控件
        TextView leftTextView;
        TextView rightTextView;

        // 为内部类的构造函数,传入的参数View就是滚动控件中每一个单元项的布局文件View
        public ViewHolder (View view) {
            super(view);
            // 在此处获取布局文件的控件
            leftTextView = (TextView) view.findViewById(R.id.textview_item_left);
            rightTextView = (TextView) view.findViewById(R.id.textview_item_right);
        }
    }
    // RecyclerViewAdapter类的构造函数,我们会从MainActivity中给它传入一个List,作为
    // 滚动控件中要显示的所有项目,每一个对象即为一个单元项
    // 或者也可以传进来两个三个四个参数啥的,皆可自行DIY
    public RecyclerViewAdapter(List<RecyclerViewItem> recyclerViewItemList) {
        this.recyclerViewItemList = recyclerViewItemList;
    }

    // 是RecyclerViewAdapter类继承RecyclerView.Adapter所需要实现的虚函数(抽象方法)
    // 按下Alt+Insert键选择Implement Methods全选添加
    // Override表示其下一行的方法是父类的方法,在此处重写(实现)
    // 此方法可为每一个单元项设置单击事件
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    // 此方法表示该如何显示每一个单元项
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

    }
	
	// 返回单元项的个数,只需要改成这样既可 
    @Override
    public int getItemCount() {
        return recyclerViewItemList.size();
    }
}

这样以来,适配器的基本框架就搭起来了,我们接下来需要完善两个函数,即onCreateViewHolder和onBindViewHolder,两个从父类继承而需要实现的两个接口方法。

我们先看onBindViewHolder方法,这个方法表示该如何显示每一个单元项中的内容

    // 此方法表示该如何显示每一个单元项
    // 第一个参数表示我们在这个类RecyclerViewAdapter里面创建的内部类ViewHolder
    // 而这个holder也就是单元项的布局文件
    // 第二个参数表示现在该显示第几个单元项了,从0开始计数
    // 我们可以采用 position%2==1 的方式来分奇偶项分别处理,或者其他
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // 先从recyclerViewItemList中获取第position个对象,作为操作的内容
        // 这里的编写中规中矩,各位也可以根据自己的想法DIY
        RecyclerViewItem recyclerViewItem = recyclerViewItemList.get(position);
        holder.leftTextView.setText(recyclerViewItem.getLeftString());
        holder.rightTextView.setText(recyclerViewItem.getRightString());
    }

然后就是设置每一项的单击事件onCreateViewHolder方法,这个我们可以稍后讲解,现在先不设置任何单击事件

    // 是RecyclerViewAdapter类继承RecyclerView.Adapter所需要实现的虚函数(抽象方法)
    // 按下Alt+Insert键选择Implement Methods全选添加
    // Override表示其下一行的方法是父类的方法,在此处重写(实现)
    // 此方法可为每一个单元项设置单击事件
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 从父对象中获取到我们需要的那个Layout,即R.layout.recyclerview_item。
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
        // 创建onBindViewHolder对象中需要的ViewHolder对象,这个时候会调用我们写的ViewHolder内部类的构造方法
        ViewHolder viewHolder = new ViewHolder(view);
        // 这个地方必须返回这个东西,不然的话下面的onBindViewHolder方法也就获取不到holder了,就会报空指针异常了
        return viewHolder;
    }

到此为止,我们的适配器就告一段落了。

5.输入数据(代码层次的)

这个时候我们需要给前端的RecyclerView这个控件传输数据,这样它才能正常显示可以滚动的信息
大致的流程是:我们现在MainActivity中创建滚动控件中所需要的数据数组,然后我们把它传给适配器,接着我们把这个适配器指定给前端页面的RecyclerView控件。

1. 在MainActivity中初始化信息
需要注意的是,哪怕只有一个前端的控件需要跟后端的对象建立联系,最好也要使用initData()这样的形式,明了,清晰,也易删改。有利于养成良好的编译习惯
Android应用开发--RecyclerView滚动控件
2.开始传输数据给Adapter

    // 这个是前端页面RecyclerView在后台的代言人
    private RecyclerView mainRecyclerView;
    // 这个是存储所有滚动控件中数据的数组
    private List<RecyclerViewItem> recyclerViewItemList = new ArrayList<RecyclerViewItem>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();

        // 这两句语句表示指定RecyclerView控件的布局方式
        // 这里我们选用了LinearLayout的线性布局方式
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mainRecyclerView.setLayoutManager(layoutManager);

        // 这一句即是创建一个适配器,一个我们自己编写的适配器
        // 后面的new即是调用适配器里面的构造函数,我们可以通过更改适配器的
        // 构造函数来实现传递各种的数据
        // 这里我们将我们在initList中创建的十个元素的List传给适配器
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(recyclerViewItemList);
        // 给前端页面的RecyclerView指定适配器
        mainRecyclerView.setAdapter(adapter);
    }

这里别忘了给成员变量recyclerViewItemList赋初始值,即初始化,否则在运行到recyclerViewItemList.add(temp);语句的时候会报空指针异常。只需要像我上面那样赋值即可

到此为止,一个使用RecyclerView控件的Android studio应用就写的差不多了。
大家也可以使用数据库的方式获取到数据,在initList方法中创建从数据库获取的数据信息列表

这个时候我们如果运行测试的话会是这样
Android应用开发--RecyclerView滚动控件
为了增强可读性,我们给recyclerview_item.xml布局文件中添加两行属性,变成这样,就能看到我们一开始展示的内容了

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:layout_marginBottom="10dp"
    android:background="#ffff00"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

6.为每个单元项设置单击事件

需要注意的是,在给它设置单击事件的时候,要将vewHolder设置为final的类型

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 从父对象中获取到我们需要的那个Layout,即R.layout.recyclerview_item。
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
        // 创建onBindViewHolder对象中需要的ViewHolder对象,这个时候会调用我们写的ViewHolder内部类的构造方法
        final ViewHolder viewHolder = new ViewHolder(view);
        viewHolder.leftTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取当前用户单击的单元项索引,即用户单击的是第几个单元项
                int position = viewHolder.getAdapterPosition();
                // 获取数组列表中索引为position的对象,以此来获取用户点击的那一个单元项的内容
                RecyclerViewItem recyclerViewItem = recyclerViewItemList.get(position);
                // 获取当前的上下文,可以通过这个来使用Intent进行页面跳转
                Context context = v.getContext();
            }
        });
        // 这个地方必须返回这个东西,不然的话下面的onBindViewHolder方法也就获取不到holder了,就会报空指针异常了
        return viewHolder;
    }