Database中的使用
Paging在Database中的使用非常简单,它与Room结合将操作简单到了极致,我这里将其归纳于三步。
- 使用DataSource.Factory来获取Room中的数据
- 使用LiveData来观察PagedList
- 使用PagedListAdapter来与数据进行绑定与更新
DataSource.Factory
首先第一步我们需要使用DataSource.Factory抽象类来获取Room中的数据,它内部只要一个create抽象方法,这里我们无需实现,Room会自动帮我们创建PositionalDataSource实例,它将会实现create方法。所以我们要做的事情非常简单,如下:
@Dao
interface ArticleDao {
// PositionalDataSource
@Query("SELECT * FROM article")
fun getAll(): DataSource.Factory<Int, ArticleModel>
}
我们只需拿到实现DataSource.Factory抽象的实例即可。
第一步就这么简单,接下来看第二步
LiveData
现在我们在ViewMode中调用上面的getAll方法获取所有的文章信息,并且将返回的数据封装成一个LiveData,具体如下:
class PagingViewModel(app: Application) : AndroidViewModel(app) {
private val dao: ArticleDao by lazy { AppDatabase.getInstance(app).articleDao() }
val articleList = dao.getAll()
.toLiveData(Config(
pageSize = 5
))
}
通过DataSource.Factory的toLiveData扩展方法来构建PagedList的LiveData数据。其中Config中的参数代表每页请求的数据个数。
我们已经拿到了LiveData数据,接下来进入第三步
PagedListAdapter
前面已经说了,我们要实现PagedListAdapter,并将第二步拿到的数据传入给它。
PagedListAdapter与RecyclerView.Adapter的使用区别不大,只是对getItemCount与getItem进行了重写,因为它使用到了DiffUtil,避免对数据的无用更新。
class PagingAdapter : PagedListAdapter<ArticleModel, PagingVH>(diffCallbacks) {
companion object {
private val diffCallbacks = object : DiffUtil.ItemCallback<ArticleModel>() {
override fun areItemsTheSame(oldItem: ArticleModel, newItem: ArticleModel): Boolean = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: ArticleModel, newItem: ArticleModel): Boolean = oldItem == newItem
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagingVH = PagingVH(R.layout.item_paging_article_layout, parent)
override fun onBindViewHolder(holder: PagingVH, position: Int) = holder.bind(getItem(position))
}
这样adapter也已经构建完成,最后一旦PagedList被观察到,使用submitList传入到adapter即可。
viewModel.articleList.observe(this, Observer {
adapter.submitList(it)
})