LoginSignup
10
4

More than 5 years have passed since last update.

Paging Libraryと既存のRepositoryクラスを使ってPagingする

Last updated at Posted at 2018-05-28

はじめに

Paging Libraryを使いたいが既にRepositoryパターンを適用している場合、公式ドキュメントにあるようなDaoの返り値にDataSource.Factory 使うことが難しいケースが多々あるかと思います。
この場合Repositoryをwrapして独自のDataSouceクラスを定義する手法を使うと、既存のRepositoryを活かしつつPaging Libraryを導入することができます。

ここでは以下のようなRepositoryを例にその方法を紹介していきます。

data class User(val id: Long, val name: String, val age: Int)

interface UserRepository {
   /**
    * [User.age]がageよりも大きく、[User.id]がoffsetIdよりも大きいUserを10件取得します
    */
   fun findOlderThan(age: Int, offsetId: Long?) : List<User>
}

DataSourceの構築

DataSourceにはいくつかの抽象クラスが用意されており、データ構造に適したものを選択して使います。

ここではItemKeyedDataSourceを使って構築してみます。

class UserDataSourceFactory(
    private val age: Int, 
    private val userRepository: UserRepository) : ItemKeyedDataSource<Long, User>() {

    override fun getKey(item: User): Long = item.id

    override fun loadInitial(params: LoadInitialParams<Long>, callback: LoadInitialCallback<User>) {
         userRepository.findOlderThan(age, null)
             .let { callback.onResult(it) }
    }

    override fun loadAfter(params: LoadParams<Long>, callback: LoadCallback<User>) {
         userRepository.findOlderThan(age, params.key)
             .let { callback.onResult(it) }
    }

    override fun loadBefore(params: LoadParams<Long>, callback: LoadCallback<User>) {
    }
}

ItemKeyedDataSource<Key, Value> のKeyには 取得済みがどこまでか決定できるパラメータを使います。
ここでは User.id がその役割を担い Key にはLong型をあてています。

Value は取得対象のクラス、ここでは User がそれにあたります。

DataSourceを使ってみる

独自に構築したDataSourceは以下のように使用します

  1. DataSource.Factory<Key, Value> を継承したクラスでDataSourceを提供する
  2. LivePagedListBuilder で1とpaging設定を施してLiveData<PagedList<Value>>を取得
  3. 2を購読してviewに反映する
class UserViewModel(private val: userRepository: UserRepository) : ViewModel() {

    fun olderThan(age: Int): LiveData<PagedList<User>> {
         val dataSourceFactory = object : DataSource.Factory<Long, User> {
              override fun create(): DataSource<Long, User> = UserDataSourceFactory(age, userRepository)
         }
         return LivePagedListBuilder(
                   dataSourceFactory, 
                   PagedList.Config.Builder()...build()
         ).build()
    } 

}

これで既存のRepositoryクラスに変更を加えることなくPaging Libraryを導入することができるかと思います。

参考

10
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4