Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get data from DataSource.Factory

I have to call this method to get all the persons. I cannot modify this method at all.

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

Then in an Activity I am calling it like this:

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

    val data = dao.getElements()
}

I want to get all the Persons, possibly as a list. How do I do this?

I don't understand how DataSource.Factory<Int, Person> works.

like image 412
J_Strauton Avatar asked Apr 21 '26 23:04

J_Strauton


2 Answers

According to the 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 sample code is as following:

// 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()

So you need to pass your DataSource.Factory<Int, Person> object to LivePagedListBuilder and at the end you will get LiveData<PagedList<Person>> which you can observe.


After that you need to connect LiveData to a PagedListAdapter as shown in the following code snippet:

private val adapter = YourDataAdapter()

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

The sample code of adapter you can find here.

like image 184
Sergey Avatar answered Apr 24 '26 11:04

Sergey


We use Datasource when we want to do pagination using the android paging component. there are so many ways to achieve it,

First implement paging library

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

Now the most simple method to convert data source into LiveData> is this

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

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

}

you can also pass configuration instead on 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()

}

Now create your pager adapter and view holder like this

    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
        }
    }
}

after that, in your activity or fragment you can simply observer the data change using viewmodel and submit your data to the adapter

 viewModel.getElementsLiveData().observer(this, Observer{pagedList->
  adaoter.submitList(pagedList)
 })
like image 44
Hamza Khan Avatar answered Apr 24 '26 12:04

Hamza Khan