Android RecycleView

用法
导入依赖库
1
implementation 'androidx.recyclerview:recyclerview:1.0.0'
主布局添加控件
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</LinearLayout>
子布局 fruit_item.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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"
android:orientation="horizontal">

<ImageView
android:id="@+id/fruit_image"
android:layout_width="32dp"
android:layout_height="32dp" />

<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:layout_marginLeft="10dp" />

</LinearLayout>
实体类 Fruit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}
}
新建类FruitAdapter继承自RecyclerView.Adapter,指定泛型为FruitAdapter.ViewHolder(在该adapter中新建ViewHolder类继承自RecyclerView.ViewHolder)
  • 首先定义了内部类 ViewHolder,继承自RecyclerView.ViewHolder,其中传入了一个itemView参数,这个参数继承通常是RecycleView子项的最外层布局,通过它就能取到 ImageViewTextView
  • 必须重写的三个方法
    • onCreateViewHolder(): 用来创建ViewHolder实例,在这个方法中,将 子布局 传入创建的ViewHolder实例,然后将其返回
    • onBindViewHolder():对RecyclerView子项数据赋值,会在子项布局滚动到屏幕时执行
    • getItemCount():返回数据源的长度,用来判断子布局的个数
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
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

private List<Fruit> mFruitList; //需要传入一个数据集合来构建adapter

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

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false); //传入子项布局 fruit_item 构建view 进而构建viewholder
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
}

@Override
public int getItemCount() {
return mFruitList.size(); //list.size()直接得到数量
}

static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;

public ViewHolder(@NonNull View itemView) {
super(itemView);
fruitImage = (ImageView) itemView.findViewById(R.id.fruit_image);
fruitName = (TextView) itemView.findViewById(R.id.fruit_name);
}
}
}
主活动修改
  • 先通过initFruit()初始化水果数据,接着创建RecycleView实例,然后创建了一个LinearLayoutManger对象,并将它设置到RecycleView中,表示使用线性布局,最后创建FruitAdapter实例建立数据关联
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
public class MainActivity extends AppCompatActivity {

private List<Fruit> fruitList = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initFruits();
FruitAdapter adapter = new FruitAdapter(fruitList);
RecyclerView recyclerView = findViewById(R.id.recycler_view);

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//记住 recyclerView需要设置两个东西,一个是布局,一个是adapter
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}

private void initFruits(){
for (int i = 0; i < 2; i++){
Fruit apple = new Fruit("苹果", R.drawable.apple);
fruitList.add(apple);
Fruit banana = new Fruit("香蕉", R.drawable.banana);
fruitList.add(banana);
Fruit orange = new Fruit("橙子", R.drawable.orange);
fruitList.add(orange);
Fruit watermelon = new Fruit("西瓜", R.drawable.watermelon);
fruitList.add(watermelon);
Fruit pear = new Fruit("梨", R.drawable.pear);
fruitList.add(pear);
Fruit grape = new Fruit("葡萄", R.drawable.grape);
fruitList.add(grape);
Fruit pineapple = new Fruit("菠萝", R.drawable.pineapple);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("草莓", R.drawable.strawberry);
fruitList.add(strawberry);
Fruit cherry = new Fruit("樱桃", R.drawable.cherry);
fruitList.add(cherry);
Fruit mango = new Fruit("芒果", R.drawable.mango);
fruitList.add(mango);
}
}
}
横向滚动

只修改调用的LineatLayout属性,修改为水平,加入一行代码即可

1
2
3
4
5
6
7
8
9
10
11
12
13
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initFruits();
FruitAdapter adapter = new FruitAdapter(fruitList);
RecyclerView recyclerView = findViewById(R.id.recycler_view);

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); //这里修改为水平
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
瀑布流效果

使用StaggeredGridLayoutManger布局,仅修改一行代码:

  • StaggeredGridLayoutManger的构造函数接收两个参数,第一个参数用来指定布局列数;第二个参数指定排列方向
1
2
3
4
5
6
7
8
9
10
11
12
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initFruits();
FruitAdapter adapter = new FruitAdapter(fruitList);
RecyclerView recyclerView = findViewById(R.id.recycler_view);

StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
点击事件简单实现
  • 多种方式,可在onBindViewHolder()中实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    final Fruit fruit = mFruitList.get(position);
    holder.fruitImage.setImageResource(fruit.getImageId());
    holder.fruitName.setText(fruit.getName());
    holder.fruitImage.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Log.d("tag",fruit.getName());
    }
    });
    }
0%