1. build.gradle 添加引用库
def paging_version = "3.1.1"
// //google分页库 无感知预加载
implementation "androidx.paging:paging-runtime:$paging_version"
// alternatively - without Android dependencies for tests
//testImplementation "androidx.paging:paging-common:$paging_version"
def lifecycle_version = "2.6.0-alpha01"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// ViewModel utilities for Compose
//implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-paging:$room_version"
2. 数据库管理
2.1 Student.java
@Entity(tableName = "student_table")
public class Student {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "student_number")
private int studentNumber;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
}
2.2 StudentDao.java
@Dao
public interface StudentDao {
@Insert
void insertStudents(Student... students);
@Query("DELETE FROM student_table")
void deleteAllStudents();
@Query("SELECT * FROM student_table ORDER BY id")
PagingSource<Integer, Student> getAllStudents();
// DataSource.Factory<Integer, Student> getAllStudents();
}
2.3 StudentsDatabase.java
@Database(entities = {Student.class}, version = 1, exportSchema = false)
public abstract class StudentsDatabase extends RoomDatabase {
public static StudentsDatabase instance;
public static synchronized StudentsDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(context, StudentsDatabase.class, "students_database").build();
}
return instance;
}
public abstract StudentDao getStudentDao();
}
3. 创建列表视频器
3.1 布局文件 cell.xml
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.2 MyPagedAdapter.java
public class MyPagedAdapter extends PagingDataAdapter<Student, MyPagedAdapter.MyViewHolder> {
public MyPagedAdapter() {
super(new DiffUtil.ItemCallback<Student>() {
@Override
public boolean areItemsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
return oldItem.getId() == newItem.getId();
}
@Override
public boolean areContentsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
return oldItem.getStudentNumber() == newItem.getStudentNumber();
}
});
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.cell, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Student student = getItem(position);
if (student == null) {
holder.textView.setText("loading");
} else {
holder.textView.setText(String.valueOf(student.getStudentNumber()));
}
}
static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
}
}
4. 调用测试页
4.1 activity_main.xml
<?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.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.9" />
<Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清空"
app:layout_constraintBottom_toBottomOf="@+id/btn_populate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btn_populate"
app:layout_constraintTop_toTopOf="@+id/btn_populate" />
<Button
android:id="@+id/btn_populate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="生成"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_clear"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline2" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/guideline2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
4.2 MainActivity.xml
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
Button btnPopulate, btnClear;
StudentDao studentDao;
StudentsDatabase studentsDatabase;
MyPagedAdapter pagedAdapter;
LiveData<PagingData<Student>> allStudentsLivePaging;
//LiveData<PagedList<Student>> allStudentsLivePaged;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
pagedAdapter = new MyPagedAdapter();
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
recyclerView.setAdapter(pagedAdapter);
studentsDatabase = StudentsDatabase.getInstance(this);
studentDao = studentsDatabase.getStudentDao();
//allStudentsLivePaging = new LivePagedListBuilder<>(studentDao.getAllStudents(),30).build();
//初始化配置,可以定义最大加载的数据量
Pager<Integer, Student> pager = new Pager<>(new PagingConfig(20), () -> studentDao.getAllStudents());
allStudentsLivePaging = PagingLiveData.getLiveData(pager);
allStudentsLivePaging.observe(this, new Observer<PagingData<Student>>() {
@Override
public void onChanged(PagingData<Student> pagingData) {
pagedAdapter.submitData(getLifecycle(), pagingData);
}
});
btnPopulate = findViewById(R.id.btn_populate);
btnClear = findViewById(R.id.btn_clear);
btnPopulate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Student[] students = new Student[500];
for (int i = 0; i < 500; i++) {
Student student = new Student();
student.setStudentNumber(i);
students[i] = student;
}
new InsertAsyncTack(studentDao).execute(students);
}
});
btnClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new ClearAsyncTack(studentDao).execute();
}
});
}
static class InsertAsyncTack extends AsyncTask<Student, Void, Void> {
StudentDao studentDao;
public InsertAsyncTack(StudentDao studentDao) {
this.studentDao = studentDao;
}
@Override
protected Void doInBackground(Student... students) {
studentDao.insertStudents(students);
return null;
}
}
static class ClearAsyncTack extends AsyncTask<Void, Void, Void> {
StudentDao studentDao;
public ClearAsyncTack(StudentDao studentDao) {
this.studentDao = studentDao;
}
@Override
protected Void doInBackground(Void... voids) {
studentDao.deleteAllStudents();
return null;
}
}
}
5. 效果图