「potatotips #83 iOS/Android開発Tips共有会」で発表した資料になります。
#potatotips #83©2023 RAKUS Co., Ltd.Jetpack ComposeとPaging3で実現するEndless Grid Designpotatotips #83 iOS/Android開発Tips共有会@akkiee76
View Slide
#potatotips #83Akihiko Sato株式会社ラクス 楽楽精算 Lead Engineerコールドブリューコーヒー☕ / パン作り🍞 / あんバターフランス🥐@akkiee76自己紹介
#potatotips #83ページングライブラリ概要大規模なデータセットからデータのページをローカルストレージやネットワーク経由で読み込んで表示することができるライブラリです
#potatotips #83ページングライブラリの主な機能● ページングデータに対するメモリ内キャッシュ● 組み込みのリクエスト重複排除● 読込まれたデータの一番下までスクロールすると、データが自動的にリクエストされる構成が可能● 更新機能や再試行機能などエラー処理の組込みをサポート● Kotlinコルーチンとフロー、LiveData、RxJava に対応
#potatotips #83ページングライブラリの主な機能● ページングデータに対するメモリ内キャッシュ● 組み込みのリクエスト重複排除● 読込まれたデータの一番下までスクロールすると、データが自動的にリクエストされる構成が可能● 更新機能や再試行機能などエラー処理の組込みをサポート● Kotlinコルーチンとフロー、LiveData、RxJava に対応リソースを効率的にしたページングデータの操作が可能に
#potatotips #83サンプルアプリ主に使用しているライブラリなど● paging 3● paging-compose 3● coil● Unsplash Image APIhttps://github.com/akkie76/Paging-App-Sample
#potatotips #83ページングライブラリの主なクラス● PagingData● Pager● PagingSource● PagingConfig● LazyPagingItems
#potatotips #83ページングライブラリの主なクラス● PagingData○ ページングによりロードされたデータクラス● Pager● PagingSource● PagingConfig● LazyPagingItems
#potatotips #83ページングライブラリの主なクラス● PagingData● Pager○ PagingDataのリアクティブストリームを行うクラス● PagingSource● PagingConfig● LazyPagingItems
#potatotips #83ページングライブラリの主なクラス● PagingData● Pager● PagingSource○ 表示するデータソースを取得するクラス● PagingConfig● LazyPagingItems
#potatotips #83ページングライブラリの主なクラス● PagingData● Pager● PagingSource● PagingConfig○ PagingSource で取得するデータをロードする際の設定クラス● LazyPagingItems
#potatotips #83ページングライブラリの主なクラス● PagingData● Pager● PagingSource● PagingConfig● LazyPagingItems○ PagingData のフローから取得したデータを表示するためのクラス
#potatotips #83アーキテクチャ
#potatotips #83Repository
#potatotips #83Repositoryclass UnsplashSearchRepositoryImpl @Inject constructor(private val service: UnsplashService): UnsplashSearchRepository {override fun searchPhotos(query: String): Flow> {return Pager(config = PagingConfig(enablePlaceholders = false, pageSize = PAGE_SIZE),pagingSourceFactory = { UnsplashPagingSource(service, query) }).flow}companion object {private const val PAGE_SIZE = 25}}
#potatotips #83Repositoryclass UnsplashPagingSource(private val service: UnsplashService,private val query: String) : PagingSource() {override suspend fun load(params: LoadParams): LoadResult {val page = params.key ?: UNSPLASH_STARTING_PAGE_INDEXreturn try {val response = service.searchPhotos(query, page, params.loadSize)val photos = response.resultsLoadResult.Page(data = photos,prevKey = if (page == UNSPLASH_STARTING_PAGE_INDEX) null else page - 1,nextKey = if (page == response.totalPages) null else page + 1)} catch (exception: Exception) {LoadResult.Error(exception)}}
#potatotips #83ViewModel
#potatotips #83ViewModel@HiltViewModelclass MainViewModel @Inject constructor(searchRepository: UnsplashSearchRepository): ViewModel() {val photos = searchRepository.searchPhotos(QUERY).cachedIn(viewModelScope)companion object {private const val QUERY = "fruit"}}
#potatotips #83UI Layer
#potatotips #83UI Layer@Composablefun MainScreen(viewModel: MainViewModel) {Scaffold { padding ->val lazyPagingItems = viewModel.photos.collectAsLazyPagingItems()LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) {items(count = lazyPagingItems.itemCount,key = lazyPagingItems.itemKey()) { index ->val photo = lazyPagingItems[index] ?: return@itemsAsyncImage(model = photo.urls.small,contentDescription = null,modifier = Modifier.fillMaxWidth().height(128.dp),contentScale = ContentScale.FillWidth)}}
#potatotips #83UI Layer(CircularProgress)when (lazyPagingItems.loadState.refresh) {is LoadState.Loading -> {Column(modifier = Modifier.fillMaxSize(),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center,) {Text(modifier = Modifier.padding(8.dp),text = "Loading")CircularProgressIndicator(modifier = Modifier.padding(top = 8.dp),color = Color.LightGray)}}else -> {}}
#potatotips #83まとめページングライブラリを使うと、シンプルな実装でリソースを効率化したエンドレススクロールが実現可能です。画像読み込みライブラリも合わせて使うことで、デザインの幅も広げることも可能です。
#potatotips #83Thank you !