中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android?Jetpack?Compose無限加載列表的示例分析

發布時間:2022-01-17 14:07:00 來源:億速云 閱讀:318 作者:清風 欄目:開發技術

本文將為大家詳細介紹“Android Jetpack Compose無限加載列表的示例分析”,內容步驟清晰詳細,細節處理妥當,而小編每天都會更新不同的知識點,希望這篇“Android Jetpack Compose無限加載列表的示例分析”能夠給你意想不到的收獲,請大家跟著小編的思路慢慢深入,具體內容如下,一起去收獲新知識吧。

    前言

    Android 中使用 ListView 或者 RecycleView 經常有滾動到底部自動 LoadMore 的需求,那么在 Compose 中該如何實現呢?

    兩種方法可供選擇:

    基于 paging-compose

    自定義實現

    方法一: paging-compose

    Jetpack 的 Paging 組件提供了對 Compose 的支持

    dependencies {
        ...
        // Paging Compose    
        implementation "androidx.paging:paging-compose:$latest_version"
    }

    Paging 的無限加載列表需要依靠 Paging 的 DataSource,我們創建一個 DataSource ,并在 ViewModel 中加載

    class MyDataSource(
        private val repo: MyRepository
    ) : PagingSource<Int, MyData>() {
    
        override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MyData> {
            return try {
                val nextPage = params.key ?: 1
                val response = repo.fetchData(nextPage)
    
                LoadResult.Page(
                    data = response.results,
                    prevKey = if (nextPage == 1) null else nextPage - 1,
                    nextKey = repo.page.plus(1)
                )
            } catch (e: Exception) {
                LoadResult.Error(e)
            }
        }
    }
    
    class MainViewModel(
        repo: MyRepository
    ) : ViewModel() {
    
        val pagingData: Flow<PagingData<MyData>> = Pager(PagingConfig(pageSize = 20)) {
            MyDataSource(repo)
        }.flow
    }

    接下來在 Compose 使用 LazyColumn 或者 LazyRow 顯示 Paging 的數據

    @Composable
    fun MyList(pagingData: Flow<PagingData<MyData>>) {
        val listItems: LazyPagingItems<MyData> = pagingData.collectAsLazyPagingItems()
    
        LazyColumn {
            items(listItems) { 
                ItemCard(data = it)
            }
        }
    }

    MyList 從 ViewModel 獲取 Flow<PagingData<MyData>> 并通過 collectAsLazyPagingItems 轉換成 Compose 的 State ,最終傳遞給 LazyColumn 內的 items 中進行展示。

    注意這里的 items(...) 是 paging-compose 中為 LazyListScope 定義的擴展方法,而非通常使用的 LazyListScope#items

    public fun <T : Any> LazyListScope.items(
        items: LazyPagingItems<T>,
        key: ((item: T) -> Any)? = null,
        itemContent: @Composable LazyItemScope.(value: T?) -> Unit
    ) {
    	...
    }

    它接受的參數類型是 LazyPagingItems<T>, LazyPagingItems 在 get 時會判斷是否滑動到底部并通過 Paging 請求新的數據,以此實現了自動加載。

    方法二:自定義實現

    如果你不想使用 Paging 的 DataSource,也可以自定義一個無限加載列表的 Composable

    @Composable
    fun list() {
        val listItems = viewModel.data.observeAsState()
        LazyColumn {
            listItems.value.forEach { item ->
                item { ItemCard(item) }    
            }
            item { 
            	LaunchedEffect(Unit) {
            		viewModel.loadMore()
            	}
            }
        }
    }

    當加載到最后一個 item 時,通過 LaunchedEffect 向 viewModel 請求新的數據。
    你也可以是用下面的方法,在抵達最后一個 item 之前,提前 loadmore,

    @Composable
    fun list() {
        val listItems = viewModel.data.observeAsState()
        LazyColumn {
        	itemsIndexed(listItmes) { index, item ->
        		itemCard(item)
        		LaunchedEffect(listItems.size) {
        			if (listItems.size - index < 2) {
        				viewModel.loadMore()
        			}
        		}
    		}
        }
    }

    如上,使用 itemsIndexed() 可以在展示 item 的同時獲取當前 index,每次展示 item 時,都判斷一下是否達到 loadMore 條件,比如代碼中是當距離抵達當前列表尾部還有 2 個以內 item 。
    注意 LaunchedEffect 可能會隨著每個 item 重組而執行,為 LaunchedEffect 增加參數 listItems.size 是為了確保對其在 item 上屏時只走一次。

    添加 LoadingIndicator

    如果想在 loadMore 時顯示一個 LoadingIndicator, 可以實現代碼如下

    @Composable
    fun list() {
        val listItems = viewModel.data.observeAsState()
        val isLast = viewModel.isLast.observeAsState()
        
        LazyColumn {
            listItems.value.forEach { item ->
                item { ItemCard(item) }    
            }
    		if (isLast.value.not()) {
    		    item { 
            		LoadingIndicator()
            		LaunchedEffect(Unit) {
            			viewModel.loadMore()
            		}
            	}
    		}
        }
    }

    在展示最后一個 item 時,顯示 LoadingIndicator() ,同時 loadMore(), 當沒有數據可以加載時,不能再顯示 LoadingIndicator,所以我們必須將 isLast 作為一個狀態記錄到 ViewModel 中,當然,你也可以將 viewModel.data 和 viewModel.isLast 等所有狀態合并為一個 UiState 進行訂閱。

    Android?Jetpack?Compose無限加載列表的示例分析

    Android是什么

    Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。

    如果你能讀到這里,小編希望你對“Android Jetpack Compose無限加載列表的示例分析”這一關鍵問題有了從實踐層面最深刻的體會,具體使用情況還需要大家自己動手實踐使用過才能領會,如果想閱讀更多相關內容的文章,歡迎關注億速云行業資訊頻道!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    翁牛特旗| 鸡泽县| 海口市| 柘荣县| 汶上县| 连城县| 尚义县| 油尖旺区| 乐都县| 黄梅县| 土默特右旗| 柏乡县| 平果县| 铁力市| 安顺市| 包头市| 望谟县| 乾安县| 益阳市| 谢通门县| 滨海县| 余干县| 九寨沟县| 河西区| 五原县| 三明市| 台安县| 政和县| 绥芬河市| 双鸭山市| 淮安市| 和田县| 商南县| 资中县| 连云港市| 安平县| 离岛区| 三台县| 闸北区| 贵德县| 吉安市|