赞
踩
安卓Paging是一种分页加载数据的方法,它基于无限滚动模式而设计,可以帮助应用更高效地利用网络带宽和系统资源。Paging库可以加载和显示来自本地存储或网络中更大的数据集中的数据页面,适用于以列表的形式加载大量的数据。
Paging库具有以下功能:
1. 分页数据的内存中缓存,有助于确保应用在处理分页数据时高效使用系统资源。
2. 内置的请求去重功能,可确保应用高效利用网络带宽和系统资源。
3. 可配置的RecyclerView适配器,会在用户滚动到已加载数据的末尾时自动请求数据。
4. 对Kotlin协程和数据流以及LiveData和RxJava的一流支持。
5. 内置对错误处理功能的支持,包括刷新和重试功能。
总之,安卓Paging可以帮助开发者更有效地加载和管理大量数据,提高应用的性能和用户体验。
官方文档:Paging | Jetpack | Android Developers
- dependencies {
-
- //Room
- def room_version = "2.5.0"
- implementation "androidx.room:room-runtime:$room_version"
- annotationProcessor "androidx.room:room-compiler:$room_version"
-
- //Paging
- def paging_version = "3.2.1"
- implementation "androidx.paging:paging-runtime:$paging_version"
-
-
- }
- <?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/btnPopulate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="生成数据"
- app:layout_constraintBottom_toBottomOf="@+id/btnClean"
- app:layout_constraintEnd_toStartOf="@+id/btnClean"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="@+id/btnClean" />
-
- <Button
- android:id="@+id/btnClean"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="清除数据"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toEndOf="@+id/btnPopulate"
- app:layout_constraintTop_toTopOf="@+id/guideline2" />
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/recyclerView"
- android:layout_width="match_parent"
- 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>
- <?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="100dp">
-
- <ImageView
- android:id="@+id/item_img"
- android:layout_width="0dp"
- android:layout_height="0dp"
- app:layout_constraintBottom_toTopOf="@+id/guideline3"
- app:layout_constraintEnd_toStartOf="@+id/guideline5"
- app:layout_constraintStart_toStartOf="@+id/guideline4"
- app:layout_constraintTop_toTopOf="parent"
- app:srcCompat="@drawable/baseline_img" />
-
- <TextView
- android:id="@+id/item_tv"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:gravity="center"
- android:text="TextView"
- android:textSize="20sp"
- app:layout_constraintBottom_toTopOf="@+id/guideline3"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toEndOf="@+id/item_img"
- app:layout_constraintTop_toTopOf="parent" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/guideline3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_percent="1.0" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/guideline4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:layout_constraintGuide_percent="0.1" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/guideline5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:layout_constraintGuide_percent="0.3" />
- </androidx.constraintlayout.widget.ConstraintLayout>
- package com.example.mypaging;
-
- import androidx.room.Entity;
- import androidx.room.PrimaryKey;
-
- //实体类
- @Entity
- public class Student {
- //主键
- @PrimaryKey(autoGenerate = true)
- private int id;
-
- private String name;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
- package com.example.mypaging;
-
- import androidx.paging.DataSource;
- import androidx.room.Dao;
- import androidx.room.Insert;
- import androidx.room.Query;
-
- //接口 Dao 方法签名
- @Dao
- public interface StudentDao {
-
- //插入数据
- @Insert
- void insertStudents(Student... students);
-
- //删除数据
- @Query("delete from student")
- void deleteTBData();
-
- //查询
- @Query("select * from student order by id desc")
- DataSource.Factory<Integer, Student> getAllStudents(); //paging
- // LiveData<List<Student>> getAllStudents();
-
-
- }
- package com.example.mypaging;
-
- import android.content.Context;
-
- import androidx.room.Database;
- import androidx.room.Room;
- import androidx.room.RoomDatabase;
-
- @Database(entities = {Student.class}, version = 1, exportSchema = false)
- public abstract class StudentDataBase extends RoomDatabase {
- private static StudentDataBase studentDataBase;
-
- public static StudentDataBase getInstance(Context context) {
- if (studentDataBase == null) {
- studentDataBase = Room.databaseBuilder(context, StudentDataBase.class, "studentDB").build();
- }
- return studentDataBase;
- }
-
- public abstract StudentDao studentDao();
- }
InsertAsyncTask.java
- package com.example.mypaging;
-
- import android.os.AsyncTask;
-
- /**
- * AsyncTask 在 API 级别 30 中此字段已弃用 , 请改用标准或 Kotlin 并发实用程序
- * 插入数据 异步任务
- * android.os.AsyncTask<Params、进度、结果>
- */
- public class InsertAsyncTask extends AsyncTask<Student, Void, Void> {
-
- private StudentDao studentDao;
-
- public InsertAsyncTask(StudentDao studentDao) {
- this.studentDao = studentDao;
- }
-
- /**
- * 4个步骤
- * 执行异步任务时,任务会经历 4 个步骤:
- * <p>
- * onPreExecute(),在任务之前的 UI 线程上调用 被执行。此步骤通常用于设置任务,例如 在用户界面中显示进度条。
- * <p>
- * doInBackground(Params),在后台线程上调用 执行完毕后立即执行。
- * 此步骤用于 执行可能需要很长时间的后台计算。参数 的异步任务被传递到此步骤。
- * 计算结果必须 由此步骤返回,并将传递回最后一步。这一步 还可用于发布一个或多个单元 的进步。
- * 这些值在步骤中发布在 UI 线程上。onPreExecute()publishProgress(Progress)onProgressUpdate(Progress)
- * <p>
- * onProgressUpdate(Progress),在 UI 线程上调用 调用 。
- * 执行的时间是 定义。此方法用于在用户中显示任何形式的进度 接口,而后台计算仍在执行。
- * 例如 它可用于对进度条进行动画处理或在文本字段中显示日志。publishProgress(Progress)
- * <p>
- * onPostExecute(Result),在后台之后的 UI 线程上调用 计算完成。将后台计算的结果传递给主界面。
- */
-
- @Override
- protected Void doInBackground(Student... students) {
- studentDao.insertStudents(students);
- return null;
- }
-
- }
DeleteTBAsyncTask.java
- package com.example.mypaging;
-
- import android.os.AsyncTask;
-
-
- public class DeleteTBAsyncTask extends AsyncTask<Void, Void, Void> {
- private StudentDao studentDao;
-
- public DeleteTBAsyncTask(StudentDao studentDao) {
- this.studentDao = studentDao;
- }
-
- @Override
- protected Void doInBackground(Void... voids) {
- studentDao.deleteTBData();
- return null;
- }
- }
- package com.example.mypaging;
-
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.TextView;
-
- import androidx.annotation.NonNull;
- import androidx.recyclerview.widget.RecyclerView;
-
- // 列表中的每一项数据
- public class MyViewHolder extends RecyclerView.ViewHolder {
- TextView textView;
- ImageView imageView;
- public MyViewHolder(@NonNull View itemView) {
- super(itemView);
- textView = itemView.findViewById(R.id.item_tv);
- imageView = itemView.findViewById(R.id.item_img);
- }
- }
- package com.example.mypaging;
-
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
-
- import androidx.annotation.NonNull;
- import androidx.paging.PagedListAdapter;
- import androidx.recyclerview.widget.DiffUtil;
-
- public class MyPageAdapter extends PagedListAdapter<Student, MyViewHolder> {
-
- public MyPageAdapter() {
- super(new DiffUtil.ItemCallback<Student>() {
- @Override
- public boolean areItemsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
- //比较id是否相等
- return oldItem.getId() == newItem.getId();
- }
-
- @Override
- public boolean areContentsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
- //比较内容是否相等
- return oldItem.getName().equals(oldItem.getName());
- }
- });
- }
-
-
- @NonNull
- @Override
- public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- //获取视图对象
- View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, 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("正在加载...");
- } else {
- holder.textView.setText(student.getName());
- }
-
- }
-
-
- }
- package com.example.mypaging;
-
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
-
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.lifecycle.LiveData;
- import androidx.lifecycle.Observer;
- import androidx.paging.LivePagedListBuilder;
- import androidx.paging.PagedList;
- import androidx.recyclerview.widget.DividerItemDecoration;
- import androidx.recyclerview.widget.LinearLayoutManager;
- import androidx.recyclerview.widget.RecyclerView;
-
- public class MainActivity extends AppCompatActivity {
-
- private Button btnPopulate, btnClean;
-
- private StudentDataBase studentDataBase;
- private StudentDao studentDao;
- //往视图中添加数据 需要用适配器
- private RecyclerView recyclerView;
- private MyPageAdapter myPageAdapter;
-
- //数据获取
- LiveData<PagedList<Student>> allStudentsLivePaged;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- btnPopulate = findViewById(R.id.btnPopulate);
- btnClean = findViewById(R.id.btnClean);
- recyclerView = findViewById(R.id.recyclerView);
-
- myPageAdapter = new MyPageAdapter();
-
- recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
- //分隔符
- recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
- //往视图中添加适配器
- recyclerView.setAdapter(myPageAdapter);
-
- studentDataBase = StudentDataBase.getInstance(this);
- studentDao = studentDataBase.studentDao();
- allStudentsLivePaged = new LivePagedListBuilder<>(studentDao.getAllStudents(), 3).build();
- //观察
- allStudentsLivePaged.observe(this, new Observer<PagedList<Student>>() {
- @Override
- public void onChanged(PagedList<Student> students) {
- //内容发生改变
- myPageAdapter.submitList(students);
- students.addWeakCallback(null, new PagedList.Callback() {
- @Override
- public void onChanged(int i, int i1) {
- Log.e("TAG", "----观察--" + students);
- }
-
- @Override
- public void onInserted(int i, int i1) {
-
- }
-
- @Override
- public void onRemoved(int i, int i1) {
-
- }
- });
- }
- });
-
- //按钮事件
- btnPopulate.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Student[] students = new Student[100];
- for (int i = 0; i < 100; i++) {
- Student student = new Student();
- student.setName("学生"+i);
- students[i] = student;
- }
- new InsertAsyncTask(studentDao).execute(students);
- }
- });
-
- //事件
- btnClean.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new DeleteTBAsyncTask(studentDao).execute();
- }
- });
-
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。