Android应用开发--RecyclerView滚动控件
关键词:
Android手机应用开发、RecyclerView控件
开发环境:Windows 10 x64、Android studio2.2
实现功能:使用RecyclerView控件,实现一个可滚动的效果,并且控件中可滚动的每一项的内容和布局都可以*设计。
具体流程:导入工具包、在布局文件中使用、编写单元项布局、编写适配器、在后台将数据写入以在前台显示出来、为每一个单元项设计单击事件。
大致效果图,可上下滑动以显示其他内容
项目文件RecyclerView滚动控件的使用可自行下载查看
1.导入工具包
首先,在Grande Scripts/build.gradle(Module:app)上双击打开app配置文件,在其中加上这个
compile 'com.android.support:recyclerview-v7:26.+'
其中26.+
可以根据自己Android生成的SDK的版本号进行更改,比如
添加完包的信息之后,单击Sync Now,如果各位的Android studio没有自动弹出那个选项,可以直接在这个位置选择
较详细的流程可参照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中的,所必须得把完整的路径写出来,也就是全限定名
3.编写单元项的布局
首先在app/res/layout里面创建一个新的布局文件,文件名就叫做recyclerview_item
创建伊始,会有这个属性,在这里我们把它删除掉,因为我们在这里需要的是从左往右的线性布局,而非从上往下的线性布局。
android:orientation="vertical"
然后我们自定义滚动控件中每一个单元项的布局
这里需要注意的是划红线的部分,其他的布局文件这里基本都是match_parent属性,这里的wrap_content属性意味着,这个布局的高度等于它内容的总高度,也就是说这个布局的高度随着它内部内容的总高度在变化
因为我们写的这个布局是滚动控件中的其中一个单元项,所以它的高度不能是match_parent,而只能是wrap_content
4.编写适配器
适配器,简单的说就是接口转化,我们手机充电插头就可以说是一种适配器,它把220V-50Hz的电能转化为我们手机可以正常使用充电的电能;以及OTG转换头,给手机接一个USB接口,将USB口转化为我们手机的充电口。等等。
感兴趣的可以了解一下物理意义上的适配器,或者了解软件设计方面的设计模式-适配器模式。
接下来我们开始编写适配器,在编写适配器之前,我们需要一个类,来存储滚动控件中每一个单元项中所需要的数据。
例如
我们先创建一个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()这样的形式,明了,清晰,也易删改。有利于养成良好的编译习惯
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方法中创建从数据库获取的数据信息列表
这个时候我们如果运行测试的话会是这样
为了增强可读性,我们给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;
}
上一篇: Angular2自定义分页组件
下一篇: AngularJS的脏检查深入分析
推荐阅读