介绍
Paging的主要功能就是一次加载小部分数据,可以减少网络带宽和系统资源的使用
使用
本次的Demo结合了之前的数据库Room,然后那个刚好是用Kotlin写的,这次就使用Java写一遍,当然引入Paging后代码会有点出入
- 添加·Room·和·Paging·依赖
def room_version = "2.2.1"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcesso
def paging_version = "2.1.0"
implementation "androidx.paging:paging-runtime:$paging_version" // For Kotlin use paging-runtime-kt
- 创建User实体类
代码还是和之前一样
package com.example.pagingdemo;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "user")
public class User {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "name")
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;
}
}
- 创建UserDao接口类
这部分要注意,查询全部的返回值从LiveData<List<User>>
改成了DataSource.Factory<Integer, User>
package com.example.pagingdemo;
import androidx.paging.DataSource;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
@Dao
public interface UserDao {
@Insert
void insertUser(User... users);
@Query("DELETE FROM user")
void deleteUsers();
@Query("SELECT * FROM user")
DataSource.Factory<Integer, User> getAllUsers();
}
- 创建DataBase抽象类
这部分也和之前一样保持不变
@Database(entities = {User.class}, version = 1)
public abstract class AppDataBase extends RoomDatabase {
private static AppDataBase dataBase;
static synchronized AppDataBase getInstance(Context context) {
if (dataBase == null) {
dataBase = Room.databaseBuilder(context, AppDataBase.class, "user_database").build();
}
return dataBase;
}
abstract UserDao getUserDao();
}
- 创建RecyclerView的适配器
数据还是和之前的一样,用RecyclerView展示,但是使用的适配器从ListAdapter
换成了PageLitAdapter
package com.example.pagingdemo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.paging.PagedListAdapter;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
public class RecyclerViewAdapter extends PagedListAdapter<User, RecyclerViewAdapter.MyViewHolder> {
protected RecyclerViewAdapter() {
super(new DiffUtil.ItemCallback<User>() {
@Override
public boolean areItemsTheSame(@NonNull User oldItem, @NonNull User newItem) {
return oldItem.getId() == newItem.getId();
}
@Override
public boolean areContentsTheSame(@NonNull User oldItem, @NonNull User newItem) {
return oldItem.getName().equals(newItem.getName());
}
});
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
User user = getItem(position);
if (user == null) {
holder.textView.setText("loading ... ...");
} else {
holder.textView.setText(user.getName());
}
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
MyViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
}
}
这里在onBindViewHolder
中做了非空判断,为了就是当用户快速滑动视图时,数据可能还没加载出来,就给一个默认文本,提升用户体验
- 修改MainActivity
代码有点多,但实际上和之前的相比只是发生了一点点变化
因为刚才在创建UserDao接口类的时候说过,查询全部的返回值从LiveData<List<User>>
改成了DataSource.Factory<Integer, User>
,所以想要实现数据观察就需要得到LiveData
,而实现的方式就是:
LiveData<PagedList<User>> liveUserList = new LivePagedListBuilder<>(userDao.getAllUsers(), 10).build();
package com.example.pagingdemo;
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.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private AppDataBase dataBase;
private LiveData<PagedList<User>> liveUserList;
private UserDao userDao;
private RecyclerView recyclerView;
private RecyclerViewAdapter adapter;
private Button loadBtn, clearBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
adapter = new RecyclerViewAdapter();
recyclerView.setAdapter(adapter);
dataBase = AppDataBase.getInstance(this);
userDao = dataBase.getUserDao();
liveUserList = new LivePagedListBuilder<>(userDao.getAllUsers(), 10).build();
liveUserList.observe(this, new Observer<PagedList<User>>() {
@Override
public void onChanged(PagedList<User> users) {
adapter.submitList(users);
}
});
loadBtn = findViewById(R.id.load);
clearBtn = findViewById(R.id.clear);
loadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (int i = 0; i < 1000; i++) {
User user = new User();
user.setName("用户" + (i + 1));
new InsertAsyncTask(userDao).execute(user);
}
}
});
clearBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ClearAsyncTask(userDao).execute();
}
});
}
static class InsertAsyncTask extends AsyncTask<User, Void, Void> {
UserDao userDao;
InsertAsyncTask(UserDao userDao) {
this.userDao = userDao;
}
@Override
protected Void doInBackground(User... users) {
userDao.insertUser(users);
return null;
}
}
static class ClearAsyncTask extends AsyncTask<Void, Void, Void> {
UserDao userDao;
ClearAsyncTask(UserDao userDao) {
this.userDao = userDao;
}
@Override
protected Void doInBackground(Void... voids) {
userDao.deleteUsers();
return null;
}
}
}
到此就完成了Paging的简单使用
网友评论