当前位置:   article > 正文

Android :Paging (分页)加载数据-简单应用_android paging

android paging

1.Paging介绍:

安卓Paging是一种分页加载数据的方法,它基于无限滚动模式而设计,可以帮助应用更高效地利用网络带宽和系统资源。Paging库可以加载和显示来自本地存储或网络中更大的数据集中的数据页面,适用于以列表的形式加载大量的数据。

Paging库具有以下功能:

1. 分页数据的内存中缓存,有助于确保应用在处理分页数据时高效使用系统资源
2. 内置的请求去重功能,可确保应用高效利用网络带宽和系统资源。
3. 可配置的RecyclerView适配器,会在用户滚动到已加载数据的末尾时自动请求数据。
4. 对Kotlin协程和数据流以及LiveData和RxJava的一流支持。
5. 内置对错误处理功能的支持,包括刷新和重试功能。

总之,安卓Paging可以帮助开发者更有效地加载和管理大量数据,提高应用的性能和用户体验。

2.Paging使用:

官方文档:Paging  |  Jetpack  |  Android Developers

1.导入依赖:在build.gradle文件中加入

  1. dependencies {
  2. //Room
  3. def room_version = "2.5.0"
  4. implementation "androidx.room:room-runtime:$room_version"
  5. annotationProcessor "androidx.room:room-compiler:$room_version"
  6. //Paging
  7. def paging_version = "3.2.1"
  8. implementation "androidx.paging:paging-runtime:$paging_version"
  9. }

2.布局文件 activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <androidx.constraintlayout.widget.Guideline
  9. android:id="@+id/guideline2"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:orientation="horizontal"
  13. app:layout_constraintGuide_percent="0.9" />
  14. <Button
  15. android:id="@+id/btnPopulate"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:text="生成数据"
  19. app:layout_constraintBottom_toBottomOf="@+id/btnClean"
  20. app:layout_constraintEnd_toStartOf="@+id/btnClean"
  21. app:layout_constraintHorizontal_bias="0.5"
  22. app:layout_constraintStart_toStartOf="parent"
  23. app:layout_constraintTop_toTopOf="@+id/btnClean" />
  24. <Button
  25. android:id="@+id/btnClean"
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:text="清除数据"
  29. app:layout_constraintEnd_toEndOf="parent"
  30. app:layout_constraintHorizontal_bias="0.5"
  31. app:layout_constraintStart_toEndOf="@+id/btnPopulate"
  32. app:layout_constraintTop_toTopOf="@+id/guideline2" />
  33. <androidx.recyclerview.widget.RecyclerView
  34. android:id="@+id/recyclerView"
  35. android:layout_width="match_parent"
  36. android:layout_height="0dp"
  37. app:layout_constraintBottom_toTopOf="@+id/guideline2"
  38. app:layout_constraintEnd_toEndOf="parent"
  39. app:layout_constraintStart_toStartOf="parent"
  40. app:layout_constraintTop_toTopOf="parent" />
  41. </androidx.constraintlayout.widget.ConstraintLayout>

3. 里面每一项的布局  item.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="100dp">
  7. <ImageView
  8. android:id="@+id/item_img"
  9. android:layout_width="0dp"
  10. android:layout_height="0dp"
  11. app:layout_constraintBottom_toTopOf="@+id/guideline3"
  12. app:layout_constraintEnd_toStartOf="@+id/guideline5"
  13. app:layout_constraintStart_toStartOf="@+id/guideline4"
  14. app:layout_constraintTop_toTopOf="parent"
  15. app:srcCompat="@drawable/baseline_img" />
  16. <TextView
  17. android:id="@+id/item_tv"
  18. android:layout_width="0dp"
  19. android:layout_height="0dp"
  20. android:gravity="center"
  21. android:text="TextView"
  22. android:textSize="20sp"
  23. app:layout_constraintBottom_toTopOf="@+id/guideline3"
  24. app:layout_constraintEnd_toEndOf="parent"
  25. app:layout_constraintStart_toEndOf="@+id/item_img"
  26. app:layout_constraintTop_toTopOf="parent" />
  27. <androidx.constraintlayout.widget.Guideline
  28. android:id="@+id/guideline3"
  29. android:layout_width="wrap_content"
  30. android:layout_height="wrap_content"
  31. android:orientation="horizontal"
  32. app:layout_constraintGuide_percent="1.0" />
  33. <androidx.constraintlayout.widget.Guideline
  34. android:id="@+id/guideline4"
  35. android:layout_width="wrap_content"
  36. android:layout_height="wrap_content"
  37. android:orientation="vertical"
  38. app:layout_constraintGuide_percent="0.1" />
  39. <androidx.constraintlayout.widget.Guideline
  40. android:id="@+id/guideline5"
  41. android:layout_width="wrap_content"
  42. android:layout_height="wrap_content"
  43. android:orientation="vertical"
  44. app:layout_constraintGuide_percent="0.3" />
  45. </androidx.constraintlayout.widget.ConstraintLayout>

3.创建数据库

1.实体类 Student.java

  1. package com.example.mypaging;
  2. import androidx.room.Entity;
  3. import androidx.room.PrimaryKey;
  4. //实体类
  5. @Entity
  6. public class Student {
  7. //主键
  8. @PrimaryKey(autoGenerate = true)
  9. private int id;
  10. private String name;
  11. public int getId() {
  12. return id;
  13. }
  14. public void setId(int id) {
  15. this.id = id;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. }

2.创建接口 StudentDao.java

  1. package com.example.mypaging;
  2. import androidx.paging.DataSource;
  3. import androidx.room.Dao;
  4. import androidx.room.Insert;
  5. import androidx.room.Query;
  6. //接口 Dao 方法签名
  7. @Dao
  8. public interface StudentDao {
  9. //插入数据
  10. @Insert
  11. void insertStudents(Student... students);
  12. //删除数据
  13. @Query("delete from student")
  14. void deleteTBData();
  15. //查询
  16. @Query("select * from student order by id desc")
  17. DataSource.Factory<Integer, Student> getAllStudents(); //paging
  18. // LiveData<List<Student>> getAllStudents();
  19. }

3.  创建抽象类继承RoomDatabase  StudentDataBase.java

  1. package com.example.mypaging;
  2. import android.content.Context;
  3. import androidx.room.Database;
  4. import androidx.room.Room;
  5. import androidx.room.RoomDatabase;
  6. @Database(entities = {Student.class}, version = 1, exportSchema = false)
  7. public abstract class StudentDataBase extends RoomDatabase {
  8. private static StudentDataBase studentDataBase;
  9. public static StudentDataBase getInstance(Context context) {
  10. if (studentDataBase == null) {
  11. studentDataBase = Room.databaseBuilder(context, StudentDataBase.class, "studentDB").build();
  12. }
  13. return studentDataBase;
  14. }
  15. public abstract StudentDao studentDao();
  16. }

4. AsyncTask 异步任务 删除 和 保存数据方法

InsertAsyncTask.java

  1. package com.example.mypaging;
  2. import android.os.AsyncTask;
  3. /**
  4. * AsyncTask 在 API 级别 30 中此字段已弃用 , 请改用标准或 Kotlin 并发实用程序
  5. * 插入数据 异步任务
  6. * android.os.AsyncTask<Params、进度、结果>
  7. */
  8. public class InsertAsyncTask extends AsyncTask<Student, Void, Void> {
  9. private StudentDao studentDao;
  10. public InsertAsyncTask(StudentDao studentDao) {
  11. this.studentDao = studentDao;
  12. }
  13. /**
  14. * 4个步骤
  15. * 执行异步任务时,任务会经历 4 个步骤:
  16. * <p>
  17. * onPreExecute(),在任务之前的 UI 线程上调用 被执行。此步骤通常用于设置任务,例如 在用户界面中显示进度条。
  18. * <p>
  19. * doInBackground(Params),在后台线程上调用 执行完毕后立即执行。
  20. * 此步骤用于 执行可能需要很长时间的后台计算。参数 的异步任务被传递到此步骤。
  21. * 计算结果必须 由此步骤返回,并将传递回最后一步。这一步 还可用于发布一个或多个单元 的进步。
  22. * 这些值在步骤中发布在 UI 线程上。onPreExecute()publishProgress(Progress)onProgressUpdate(Progress)
  23. * <p>
  24. * onProgressUpdate(Progress),在 UI 线程上调用 调用 。
  25. * 执行的时间是 定义。此方法用于在用户中显示任何形式的进度 接口,而后台计算仍在执行。
  26. * 例如 它可用于对进度条进行动画处理或在文本字段中显示日志。publishProgress(Progress)
  27. * <p>
  28. * onPostExecute(Result),在后台之后的 UI 线程上调用 计算完成。将后台计算的结果传递给主界面。
  29. */
  30. @Override
  31. protected Void doInBackground(Student... students) {
  32. studentDao.insertStudents(students);
  33. return null;
  34. }
  35. }

DeleteTBAsyncTask.java

  1. package com.example.mypaging;
  2. import android.os.AsyncTask;
  3. public class DeleteTBAsyncTask extends AsyncTask<Void, Void, Void> {
  4. private StudentDao studentDao;
  5. public DeleteTBAsyncTask(StudentDao studentDao) {
  6. this.studentDao = studentDao;
  7. }
  8. @Override
  9. protected Void doInBackground(Void... voids) {
  10. studentDao.deleteTBData();
  11. return null;
  12. }
  13. }

4.创建适配器

1. MyViewHolder.java

  1. package com.example.mypaging;
  2. import android.view.View;
  3. import android.widget.ImageView;
  4. import android.widget.TextView;
  5. import androidx.annotation.NonNull;
  6. import androidx.recyclerview.widget.RecyclerView;
  7. // 列表中的每一项数据
  8. public class MyViewHolder extends RecyclerView.ViewHolder {
  9. TextView textView;
  10. ImageView imageView;
  11. public MyViewHolder(@NonNull View itemView) {
  12. super(itemView);
  13. textView = itemView.findViewById(R.id.item_tv);
  14. imageView = itemView.findViewById(R.id.item_img);
  15. }
  16. }

2. MyPageAdapter.java

  1. package com.example.mypaging;
  2. import android.view.LayoutInflater;
  3. import android.view.View;
  4. import android.view.ViewGroup;
  5. import androidx.annotation.NonNull;
  6. import androidx.paging.PagedListAdapter;
  7. import androidx.recyclerview.widget.DiffUtil;
  8. public class MyPageAdapter extends PagedListAdapter<Student, MyViewHolder> {
  9. public MyPageAdapter() {
  10. super(new DiffUtil.ItemCallback<Student>() {
  11. @Override
  12. public boolean areItemsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
  13. //比较id是否相等
  14. return oldItem.getId() == newItem.getId();
  15. }
  16. @Override
  17. public boolean areContentsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
  18. //比较内容是否相等
  19. return oldItem.getName().equals(oldItem.getName());
  20. }
  21. });
  22. }
  23. @NonNull
  24. @Override
  25. public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  26. //获取视图对象
  27. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
  28. return new MyViewHolder(view);
  29. }
  30. @Override
  31. public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
  32. //获取数据
  33. Student student = getItem(position);
  34. if (student == null) {
  35. //容器中还没有数据时
  36. holder.textView.setText("正在加载...");
  37. } else {
  38. holder.textView.setText(student.getName());
  39. }
  40. }
  41. }

5. MainActivity.java

  1. package com.example.mypaging;
  2. import android.os.Bundle;
  3. import android.util.Log;
  4. import android.view.View;
  5. import android.widget.Button;
  6. import androidx.appcompat.app.AppCompatActivity;
  7. import androidx.lifecycle.LiveData;
  8. import androidx.lifecycle.Observer;
  9. import androidx.paging.LivePagedListBuilder;
  10. import androidx.paging.PagedList;
  11. import androidx.recyclerview.widget.DividerItemDecoration;
  12. import androidx.recyclerview.widget.LinearLayoutManager;
  13. import androidx.recyclerview.widget.RecyclerView;
  14. public class MainActivity extends AppCompatActivity {
  15. private Button btnPopulate, btnClean;
  16. private StudentDataBase studentDataBase;
  17. private StudentDao studentDao;
  18. //往视图中添加数据 需要用适配器
  19. private RecyclerView recyclerView;
  20. private MyPageAdapter myPageAdapter;
  21. //数据获取
  22. LiveData<PagedList<Student>> allStudentsLivePaged;
  23. @Override
  24. protected void onCreate(Bundle savedInstanceState) {
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.activity_main);
  27. btnPopulate = findViewById(R.id.btnPopulate);
  28. btnClean = findViewById(R.id.btnClean);
  29. recyclerView = findViewById(R.id.recyclerView);
  30. myPageAdapter = new MyPageAdapter();
  31. recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
  32. //分隔符
  33. recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
  34. //往视图中添加适配器
  35. recyclerView.setAdapter(myPageAdapter);
  36. studentDataBase = StudentDataBase.getInstance(this);
  37. studentDao = studentDataBase.studentDao();
  38. allStudentsLivePaged = new LivePagedListBuilder<>(studentDao.getAllStudents(), 3).build();
  39. //观察
  40. allStudentsLivePaged.observe(this, new Observer<PagedList<Student>>() {
  41. @Override
  42. public void onChanged(PagedList<Student> students) {
  43. //内容发生改变
  44. myPageAdapter.submitList(students);
  45. students.addWeakCallback(null, new PagedList.Callback() {
  46. @Override
  47. public void onChanged(int i, int i1) {
  48. Log.e("TAG", "----观察--" + students);
  49. }
  50. @Override
  51. public void onInserted(int i, int i1) {
  52. }
  53. @Override
  54. public void onRemoved(int i, int i1) {
  55. }
  56. });
  57. }
  58. });
  59. //按钮事件
  60. btnPopulate.setOnClickListener(new View.OnClickListener() {
  61. @Override
  62. public void onClick(View v) {
  63. Student[] students = new Student[100];
  64. for (int i = 0; i < 100; i++) {
  65. Student student = new Student();
  66. student.setName("学生"+i);
  67. students[i] = student;
  68. }
  69. new InsertAsyncTask(studentDao).execute(students);
  70. }
  71. });
  72. //事件
  73. btnClean.setOnClickListener(new View.OnClickListener() {
  74. @Override
  75. public void onClick(View v) {
  76. new DeleteTBAsyncTask(studentDao).execute();
  77. }
  78. });
  79. }
  80. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/286575
推荐阅读
相关标签
  

闽ICP备14008679号