Android-RecyclerView

资源文件下载

添加依赖

首先在build.gradle的dependencies中添加依赖,然后sync now一下

1
2
//    添加Recyclerview依赖包
implementation 'androidx.recyclerview:recyclerview:1.1.0'

RecyclerView构建

1.创建RecyclerView布局(activity_main.xml)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical"
android:background="#336666"
android:layout_height="80dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TITLE"
android:textColor="@color/white"
android:layout_marginLeft="20dp"
android:id="@+id/listTitle"
android:textStyle="bold"
android:textSize="20sp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/recycler"
android:layout_height="match_parent"/>
</LinearLayout>

2.创建列表项的布局(item.xml)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:background="#009966">
<!-- 这里添加了一张默认图-->
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/foodIcon"
android:src="@mipmap/moren"
android:layout_marginLeft="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="NAME"
android:textStyle="bold"
android:id="@+id/foodName"
android:textColor="@color/white"
android:textSize="20sp"/>
</LinearLayout>
</LinearLayout>

3.创建RecycleView的适配器(MyAdapter)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

//MyAdapter继承自RecyclerView.Adapter并强制创建ViewHolder类进行优化
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] foodName;
private int[] foodIcon;
private Context context;
// 手动创建一个构造器,用于被外部调用时接收参数
public MyAdapter(String[] foodName,int[] foodIcon,Context context){
this.foodName = foodName;
this.foodIcon = foodIcon;
this.context = context;
}
@NonNull
@Override
// 创建ViewHolder
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 获取到布局文件,并通过MyViewHolder的构造器传递至MyViewHolder中
View view = View.inflate(context,R.layout.item,null);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}

@Override
// 事件绑定
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.foodName.setText(foodName[position]);
holder.foodIcon.setImageResource(foodIcon[position]);
}
// 定义item列表的总数
@Override
public int getItemCount() {
return foodIcon.length;
}
// MyViewHolder继承自RecyclerView的ViewHolder
// 对RecyclerView.ViewHolder进行封装
// 使MyAdapter使用ViewHolder优化
public class MyViewHolder extends RecyclerView.ViewHolder {
// 将item.xml布局文件中用到的控件定义在这里先
private TextView foodName;
private ImageView foodIcon;
// 这里的itemView即为onCreateViewHolder传入的布局文件item.xml
public MyViewHolder(@NonNull View itemView) {
super(itemView);
// 获取到item.xml中的组件
foodIcon = itemView.findViewById(R.id.foodIcon);
foodName = itemView.findViewById(R.id.foodName);
}
}
}

4.在MainActivity中对ListView进行应用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
private int[] foodIcon = new int[]{
R.mipmap.dangao,R.mipmap.cha,R.mipmap.hanbao,R.mipmap.jitui,R.mipmap.kafei,R.mipmap.kaixinguo,R.mipmap.lanmei,
R.mipmap.ningmeng,R.mipmap.niupai,R.mipmap.pijiu,R.mipmap.pisa,R.mipmap.qiyiguo,R.mipmap.regou,R.mipmap.sanmingzhi,
R.mipmap.shengnvguo,R.mipmap.shutiao,R.mipmap.tusi,R.mipmap.yimian,R.mipmap.yingtao,R.mipmap.zhangyuxiaowanzi
};
private String[] foodName = new String[]{
"蛋糕","茶","汉堡","鸡腿","咖啡","开心果","蓝莓","柠檬","牛排","啤酒","披萨","奇异果","热狗","三明治","圣女果","薯条","吐司","意面","樱桃","章鱼小丸子"
};
private RecyclerView recycler;
private TextView listTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

recycler = findViewById(R.id.recycler);
listTitle = findViewById(R.id.listTitle);
// 定义RecyclerView的item的布局
// 两个参数:上下文、列数
GridLayoutManager gridLayoutManager = new GridLayoutManager(this,2);
// 三个参数:上下文、布局方向、是否倒排序
LinearLayoutManager layoutManager = new LinearLayoutManager(this,RecyclerView.VERTICAL,false);
// 瀑布流;两个参数:列数、布局方向
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
// 设置布局
recycler.setLayoutManager(staggeredGridLayoutManager);

// 在MyAdapter中对列表进行配置
MyAdapter myAdapter = new MyAdapter(foodName,foodIcon,this);
// 将列表设置到recycler
recycler.setAdapter(myAdapter);
}
}

自定义itemOnClick

RecyclerView没有像ListView一样提供监听事件
所以要自己创建一个setOnRecyclerItemClickListener
比较繁琐,他🐎的

1.在MyAdapter类中创建一个setOnRecyclerItemClickListener方法供外部调用
1
2
3
4
5
6
//    首先创建一个setOnRecyclerItemClickListener供外部调用
// 他需要传入一个重写后的OnRecyclerItemListener对象
public void setOnRecyclerItemClickListener(OnRecyclerItemListener onRecyclerItemClickListener){
// 把传入的OnRecyclerItemListener对象赋值给实例变量中的OnRecyclerItemListener,以此供其他方法调用
this.onRecyclerItemListener = onRecyclerItemClickListener;
}
2.定义一个接口供setOnRecyclerItemClickListener定义形参

使当外部调用setOnRecyclerItemClickListener时必须使用该接口创建对象

1
2
3
4
5
6
//    定义一个接口供setOnRecyclerItemClickListener定义形参,
// 使当外部调用setOnRecyclerItemClickListener时必须使用该接口创建对象
// item执行的事件就在重写后的OnRecyclerItemClick方法中写入
public interface OnRecyclerItemListener{
void OnRecyclerItemClick(int position);
}
3.使用接口定义一个实例变量

用于将重写后的OnRecyclerItemListener对象储存于此,供其他方法调用

1
2
3
//    使用接口定义一实例变量,用于将重写后的OnRecyclerItemListener对象储存于此,供其他方法调用
private OnRecyclerItemListener onRecyclerItemListener;

4.在MyAdapter内部类MyViewHolder类的构造器中通过itemView设置监听
1
2
3
4
5
6
7
8
9
10
11
12
//    给item.xml布局文件添加OnCLick
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 实例变量OnRecyclerItemListener不为空说明setOnRecyclerItemClickListener被调用
if (onRecyclerItemListener != null){
// 那么执行OnRecyclerItemListener被重写后的OnRecyclerItemClick方法
// 并把点击item.xml的position值传入,使其可以定位点击的item.xml在RecyclerView中的位置
onRecyclerItemListener.OnRecyclerItemClick(getAdapterPosition());
}
}
});
5.MyAdapter.java完成后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

//MyAdapter继承自RecyclerView.Adapter并强制创建ViewHolder类进行优化
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] foodName;
private int[] foodIcon;
private Context context;
// 手动创建一个构造器,用于被外部调用时接收参数
public MyAdapter(String[] foodName,int[] foodIcon,Context context){
this.foodName = foodName;
this.foodIcon = foodIcon;
this.context = context;
}
@NonNull
@Override
// 创建ViewHolder
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 获取到布局文件,并通过MyViewHolder的构造器传递至MyViewHolder中
View view = View.inflate(context,R.layout.item,null);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}

@Override
// 事件绑定
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.foodName.setText(foodName[position]);
holder.foodIcon.setImageResource(foodIcon[position]);
}
// item总数
@Override
public int getItemCount() {
return foodIcon.length;
}
// MyViewHolder继承自RecyclerView的ViewHolder,使MyAdapter强制使用ViewHolder优化
public class MyViewHolder extends RecyclerView.ViewHolder {
// 将item.xml布局文件中用到的控件定义在这里先
private TextView foodName;
private ImageView foodIcon;
// 这里的itemView即为onCreateViewHolder传入的布局文件item.xml
public MyViewHolder(@NonNull View itemView) {
super(itemView);
// 获取到item.xml中的组件
foodIcon = itemView.findViewById(R.id.foodIcon);
foodName = itemView.findViewById(R.id.foodName);
// 给item.xml布局文件添加OnCLick
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 实例变量OnRecyclerItemListener不为空说明setOnRecyclerItemClickListener被调用
if (onRecyclerItemListener != null){
// 那么执行OnRecyclerItemListener被重写后的OnRecyclerItemClick方法
// 并把点击item.xml的position值传入
onRecyclerItemListener.OnRecyclerItemClick(getAdapterPosition());
}
}
});
}
}
// 首先创建一个setOnRecyclerItemClickListener供外部调用
// 他需要传入一个重写后的OnRecyclerItemListener
public void setOnRecyclerItemClickListener(OnRecyclerItemListener onRecyclerItemClickListener){
// 把传入的OnRecyclerItemListener对象赋值给实例变量中的OnRecyclerItemListener,以此供其他方法调用
this.onRecyclerItemListener = onRecyclerItemClickListener;
}
// 定义一个接口供setOnRecyclerItemClickListener定义形参,
// 使当外部调用setOnRecyclerItemClickListener时必须实现接口
// item执行的事件就在重写后的OnRecyclerItemClick方法中写入
public interface OnRecyclerItemListener{
void OnRecyclerItemClick(int position);
}
// 使用接口定义一个类变量,用于被重写后的OnRecyclerItemListener赋值,供其他方法调用
private OnRecyclerItemListener onRecyclerItemListener;
}

6.在MainActivity.java中调用
1
2
3
4
5
6
7
8
9
10
//    setOnRecyclerItemClickListener需要一个OnRecyclerItemListener接口类型参数,实现这个接口需要重写它的方法
myAdapter.setOnRecyclerItemClickListener(new MyAdapter.OnRecyclerItemListener() {
@Override
// 重写了接口的所有方法,它只有一个OnRecyclerItemClick
// 这里并不执行OnRecyclerItemClick,不过是重写它并把它作为参数给予setOnRecyclerItemClickListener
public void OnRecyclerItemClick(int position) {
// 设置item的事件
listTitle.setText(foodName[position]);
}
});

源代码

给item传入了AlertDialog对话框事件,源代码下载


写的什么🐓8玩意