如何从 DataSource.Factory 获取数据

How to get data from DataSource.Factory

我必须调用这个方法来获取所有的人。我根本无法修改此方法。

@Query("SELECT * FROM PERSON_TABLE ORDER BY NAME DESC"
abstract fun getElements(): DataSource.Factory<Int, Person>

然后在 Activity 中我这样称呼它:

override fun onCreate(...)
{
    ...

    val data = dao.getElements()
}

我想获取所有 Person,可能是一个列表。我该怎么做?

我不明白 DataSource.Factory<Int, Person> 是如何工作的。

根据 docs:

Typically, your UI code observes a LiveData object (or, if you're using RxJava2, a Flowable or Observable object), which resides in your app's ViewModel. This observable object forms a connection between the presentation and contents of your app's list data.

In order to create one of these observable PagedList objects, pass in an instance of DataSource.Factory to a LivePagedListBuilder or RxPagedListBuilder object. A DataSource object loads pages for a single PagedList. The factory class creates new instances of PagedList in response to content updates, such as database table invalidations and network refreshes. The Room persistence library can provide DataSource.Factory objects for you, or you can build your own.

示例代码如下:

// The Int type argument corresponds to a PositionalDataSource object.
val data: DataSource.Factory<Int, Person> = dao.getElements()

val dataList: LiveData<PagedList<Person>> = LivePagedListBuilder(data, /* page size */ 20).build()

所以你需要将你的DataSource.Factory<Int, Person>对象传递给LivePagedListBuilder,最后你会得到LiveData<PagedList<Person>>,你可以观察到。


之后你需要 connect LiveDataPagedListAdapter 如下代码片段所示:

private val adapter = YourDataAdapter()

override fun onCreate(savedInstanceState: Bundle?) {
    dataList.observe(this, Observer { adapter.submitList(it) })
}

您可以找到适配器的示例代码here

添加到@Sergey 的答案中,您可以使用 PagedList<>.snapshot() 获取常规列表

 // Get the DataSource from the database
 val dataSource: DataSource.Factory<Int, Person> = dao.getElements()

 // Get the dataSource as LiveData
 val data = dataSource.toLiveData(20 /* page size */)

 // In UI
 vm.data.observer(this, Observer{pagedList->
  // To get the pagedList as a regular list -
  val dataList = pagedList.snapshot()
 })

注意snapshot() 函数只为您提供 pagedList 中当前可用的项目。

当我们想使用 android 分页组件进行分页时,我们使用数据源。 有很多方法可以实现,

首先实现分页库

implementation "android.arch.paging:runtime:2.1.0"

现在最简单的数据源转LiveData的方法>就是这个

fun getElementsLiveData(): LiveData<PagedList<Person>> {

        val data = mDao.getElements()
        return LivePagedListBuilder(data, 10).build() // 10 is page size

}

您也可以通过配置代替页面大小

    fun getElementsLiveData(): LiveData<PagedList<Person>> {

     val pagedListConfig = PagedList.Config.Builder()
        .setEnablePlaceholders(true)
        .setInitialLoadSizeHint(15)
        .setPageSize(10)
        .build()

        val data = mDao.getElements()
        return LivePagedListBuilder(data, pagedListConfig).build()

}

现在像这样创建寻呼机适配器和视图容器

    class ElementAdapter(
    private val clickListener: ClickListener
) : PagedListAdapter<Person, ElementViewHolder>(diffCallback) {

    override fun onBindViewHolder(holder: ElementViewHolder, position: Int) {
        val person = getItem(position)
        with(holder) {
             // bind your data here
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ElementViewHolder =
        ElementViewHolder(parent)

    companion object {
        /**
         * This diff callback informs the PagedListAdapter how to compute list differences when new
         * PagedLists arrive.
         */
        private val diffCallback = object : DiffUtil.ItemCallback<Person>() {
            override fun areItemsTheSame(oldItem: Person, newItem: Person): Boolean =
                oldItem.id == newItem.id

            override fun areContentsTheSame(oldItem: News, newItem: News): Boolean =
                oldItem.title == newItem.title
        }
    }
}

之后,在您的 activity 或片段中,您可以使用视图模型简单地观察数据变化并将您的数据提交给适配器

 viewModel.getElementsLiveData().observer(this, Observer{pagedList->
  adaoter.submitList(pagedList)
 })