Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Paging Libraryの基本的な使い方について

162 views

Published on

Paging Libraryの基本的な使い方について

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Paging Libraryの基本的な使い方について

  1. 1. PAGING LIBRARYの基本について理解 してみた ICHI-KATO
  2. 2. ABOUT ME ▸ 加藤一郎 ▸ Kotlin歴:1年未満 ▸ 趣味:キャンプ、旅行、社会人 バスケ
  3. 3. PAGING LIBRARY
  4. 4. PAGING LIBRARYとは ▸ Android Jetpack の一部 ▸ アプリ内のRecyclerViewにおいて簡単にデータを徐々に読 み込むことができる ▸ DBのみ、ネットワークのみ、または両方に対応
  5. 5. 主要なコンポーネント ▸ DataSource ▸ データのスナップショットを取得し、PagedListに渡す。 ▸ PagedList ▸ DataSourceからデータをロードする。データの変更をRecyclerViewに教える。 ▸ PagedListAdapter ▸ RecyclerView.Adapterを実装したクラス ▸ 新しいデータがロードされた時、PagedListAdapterはRecyclerViewにデータが来た事を教える
  6. 6. 主要なコンポーネント ▸ LivePagedListBuilder ▸ DataSourceとBoundaryCallbackを指定し、LiveData<PagedList>を生成する。 ▸ BoundaryCallback ▸ PagedListが利用可能なデータの終わりに達したときに通知する。
  7. 7. 関係図 引用:https://codelabs.developers.google.com/codelabs/android-paging/index.html#2
  8. 8. サンプル https://github.com/googlecodelabs/android-paging/tree/solution
  9. 9. ライブラリの追加 Build.gradle implementation "androidx.paging:paging-runtime:$pagingVersion" その他必要なライブラリ // architecture components implementation "androidx.lifecycle:lifecycle-extensions:$archComponentsVersion" implementation "androidx.lifecycle:lifecycle-runtime:$archComponentsVersion" implementation "androidx.room:room-runtime:$roomVersion" kapt "androidx.lifecycle:lifecycle-compiler:$archComponentsVersion" kapt "androidx.room:room-compiler:$roomVersion"
  10. 10. BOUNDARYCALLBACK class RepoBoundaryCallback( private val query: String, private val service: GithubService, private val cache: GithubLocalCache ) : PagedList.BoundaryCallback<Repo>() { companion object { private const val NETWORK_PAGE_SIZE = 50 } override fun onZeroItemsLoaded() { requestAndSaveData(query) } override fun onItemAtEndLoaded(itemAtEnd: Repo) { requestAndSaveData(query) } private fun requestAndSaveData(query: String) { // APIからデータを引いてDBに保存する } } val boundaryCallback = RepoBoundaryCallback(query, service, githubLocalCache)
  11. 11. DATASOURCE fun reposByName(name: String): DataSource.Factory<Int,Repo> { return repoDao.reposByName(query) } val dataSourceFactory : DataSource.Factory<Int,Repo> = githubLocalCache.reposByName(query)
  12. 12. LIVEDATA>PAGEDLIST<の生成 val data : LiveData<PagedList<Repo>> = LivePagedListBuilder(dataSourceFactory,DATABASE_PAGE_SIZE) .setBoundaryCallback(boundaryCallback) .build()
  13. 13. VIEWMODEL class SearchRepositoriesViewModel(private val repository: GithubRepository) : ViewModel() { private val queryLiveData = MutableLiveData<String>() private val repoResult: LiveData<RepoSearchResult> = Transformations.map(queryLiveData) { // LiveData<PagedList>の生成 repository.search(it) } val repos: LiveData<PagedList<Repo>> = Transformations.switchMap(repoResult) { it -> it.data } fun searchRepo(queryString: String) { queryLiveData.postValue(queryString) } fun lastQueryValue(): String? = queryLiveData.value }
  14. 14. ADAPTER class ReposAdapter : PagedListAdapter<Repo, RecyclerView.ViewHolder>(REPO_COMPARATOR) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return RepoViewHolder.create(parent) } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val repoItem = getItem(position) if (repoItem != null) { (holder as RepoViewHolder).bind(repoItem) } } companion object { private val REPO_COMPARATOR = object : DiffUtil.ItemCallback<Repo>() { override fun areItemsTheSame(oldItem: Repo, newItem: Repo): Boolean = oldItem.fullName == newItem.fullName override fun areContentsTheSame(oldItem: Repo, newItem: Repo): Boolean = oldItem == newItem } } }
  15. 15. ACTIVITY private fun initAdapter() { list.adapter = adapter viewModel.repos.observe(this, Observer<PagedList<Repo>> { adapter.submitList(it) }) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) viewModel = ViewModelProviders.of(this, Injection.provideViewModelFactory(this)) .get(SearchRepositoriesViewModel::class.java) initAdapter() viewModel.searchRepo(query) }
  16. 16. 感想 ▸ いきなりみた時はコンポーネントが多くてちょっとよくわか らなかったが、流れを掴めばすぐに使えるようになるはず ▸ Room、ViewModelなどのアーキテクチャ コンポーネント を予めある程度わかるようにする必要がある ▸ テストをどうやって書いたら望ましいかは今模索中
  17. 17. 参考 https://developer.android.com/topic/libraries/architecture/ paging/ https://codelabs.developers.google.com/codelabs/android- paging/index.html
  18. 18. THANK YOU

×