概述
RecyclerView可以高效地顯示大量數(shù)據(jù)调鬓,并且可以自定義每個(gè)列表項(xiàng)的外觀米碰。接下來,我們會(huì)使用RecyclerView來創(chuàng)建一個(gè)列表姻蚓,用作展示一個(gè)商品的序列號(hào)、名稱和價(jià)格匣沼。運(yùn)行效果如下圖:
實(shí)現(xiàn)步驟
定義Product類
列表中需要展示商品的名稱狰挡、價(jià)格。首先,我們需要定義一個(gè)Product
類加叁,用作UI的數(shù)據(jù)呈現(xiàn)倦沧。
新創(chuàng)建一個(gè)名為data的packge(如果新增了和數(shù)據(jù)相關(guān)的類,都放到這個(gè)packge下面)它匕,再創(chuàng)建一個(gè)Product類展融。
布局文件修改
加入RecyclerView控件
在activity_main.xml中加入RecyclerView控件,將id設(shè)置為recyclerView
豫柬,代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
為列表中每個(gè)元素的外觀
1告希、創(chuàng)建一個(gè)名為cell.xml
的布局文件
2、在cell布局文件中烧给,加入3個(gè)TextView控件暂雹,分別用作展示序號(hào)、產(chǎn)品名稱创夜、產(chǎn)品價(jià)格杭跪,對(duì)應(yīng)id為:index
、name
驰吓、price
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/index"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="產(chǎn)品名稱"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/price"
app:layout_constraintStart_toStartOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="價(jià)格"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/name"
app:layout_constraintTop_toBottomOf="@+id/name" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.15085158" />
</androidx.constraintlayout.widget.ConstraintLayout>
打開ViewBinding
ViewBinding的使用可以參考:在Android中使用ViewBinding
Java代碼實(shí)現(xiàn)
自定義Adapter和ViewHolder類
ViewHolder
是列表項(xiàng)布局(即cell.xml
)的 View
容器涧尿。Adapter
會(huì)根據(jù)需要?jiǎng)?chuàng)建ViewHolder 對(duì)象
,還會(huì)為這些視圖設(shè)置數(shù)據(jù)檬贰。將視圖與其數(shù)據(jù)相關(guān)聯(lián)的過程稱為“綁定”姑廉。
新創(chuàng)建一個(gè)名為ui的packge(如果新增了和UI相關(guān)的類,都放到這個(gè)packge下面)翁涤,再創(chuàng)建一個(gè)MyAdapter類和內(nèi)部MyViewHolder類桥言。
package com.example.recyclerviewdemo.ui;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
static class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(@NonNull View itemView) {
super(itemView);
}
}
}
修改MyViewHolder類
將MyViewHolder和cell布局文件關(guān)聯(lián)起來
static class MyViewHolder extends RecyclerView.ViewHolder {
private CellBinding binding;
public MyViewHolder(@NonNull CellBinding itemView) {
super(itemView.getRoot());
binding = itemView;
}
}
修改MyAdapter
1、 修改onCreateViewHolder
每當(dāng)RecyclerView
需要?jiǎng)?chuàng)建新的ViewHolder 時(shí)葵礼,它都會(huì)調(diào)用onCreateViewHolder
号阿。此方法會(huì)創(chuàng)建并初始化ViewHolder
及其關(guān)聯(lián)的View
,但不會(huì)填充視圖的內(nèi)容鸳粉,因?yàn)?code>ViewHolder此時(shí)尚未綁定到具體數(shù)據(jù)扔涧。
在onCreateViewHolder將的cell布局文件的視圖加載起來
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private CellBinding binding;
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
binding = CellBinding.inflate(LayoutInflater.from(parent.getContext()));
return new MyViewHolder(binding);
}
... ...
}
2、修改onBindViewHolder
RecyclerView
調(diào)用此方法將ViewHolder
與數(shù)據(jù)相關(guān)聯(lián)届谈。onBindViewHolder
會(huì)提取適當(dāng)?shù)臄?shù)據(jù)枯夜,并使用該數(shù)據(jù)填充ViewHolder
的布局。
在onBindViewHolder
中給cell布局文件中的3個(gè)控件賦值艰山。為了方便演示湖雹,直接在這個(gè)方法中創(chuàng)建了一個(gè)Product對(duì)象,實(shí)際項(xiàng)目中不能這樣編寫代碼曙搬,在后續(xù)文章中會(huì)介紹如何使用ViewModel管理Product的數(shù)據(jù)摔吏。
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
// TODO: Add for test
Product product = new Product();
product.setName("哇哈哈AD鈣奶");
product.setPrice(2);
binding.name.setText(product.getName());
binding.price.setText(product.getPrice() + "¥");
binding.index.setText(String.valueOf(position + 1));
}
3汤踏、修改getItemCount
RecyclerView
調(diào)用getItemCount
來獲取數(shù)據(jù)集的大小
為了方便演示,直接返回item的個(gè)數(shù)為1
@Override
public int getItemCount() {
// TODO: Add for test
return 1;
}
設(shè)置LayoutManager
和Adpater
最后舔腾,在MainActivity
中設(shè)置RecyclerView
的LayoutManager
和Adapter
溪胶,就完成了所有代碼的編寫
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyAdapter();
binding.recyclerView.setAdapter(adapter);
}
}
運(yùn)行
運(yùn)行效果如下:
我們可以嘗試把count改成10
@Override
public int getItemCount() {
// TODO: Add for test
return 10;
}
運(yùn)行效果如下:
參考
使用 RecyclerView 創(chuàng)建動(dòng)態(tài)列表