android 如何使用Jetpack Compose实现分页列表?

ftf50wuq  于 2023-03-21  发布在  Android
关注(0)|答案(3)|浏览(315)

没有合成,我们可以处理其他Jetpack库,分页库。

cnh2zyt3

cnh2zyt31#

@ExperimentalCoroutinesApi
@Composable
fun LatestNewsFeed(viewModel: NewsViewModel) {
    val state = viewModel.newsState.collectAsState()
    val lastIndex = state.value.articles.lastIndex
    LazyColumnForIndexed(items = state.value.articles) { i, newsItem ->
        if (lastIndex == i) {
            onActive {
                viewModel.getMoreNews()
            }
        }
        NewsCard(newsItem) {
            viewModel.onSelectedNews(newsItem)
        }
    }
}

这是我的post中的一个示例,包含工作示例
这里的关键要素是:
1.观察来自State模型的数据,Jetpack Compose支持将Flow、RxJava和LiveData转换为State,在我的示例中,我使用的是Flow
1.使用onActive{}作为触发点。它只在第一次合成时被调用一次。在我的例子中,我正在检查我是否到达了最后一项,但这个逻辑可以调整。

r7s23pms

r7s23pms2#

让我更新并完成@Damine答案。重点是你必须在视图模型中添加一个方法,它可以使用偏移量获取数据。然后你可以传递下一个偏移量来获取数据。你必须处理另一个状态,它表示这是否处于网络调用的初始模式?所以第一次你将从0获取数据,然后你将使用新数据更新ui!
以免看到代码。首先你必须像这样定义状态

enum class Status {
    INITIAL,
    LOADING,
    SUCCESS,
    FAILED
}

data class NetworkState private constructor(
    val status: Status,
    val msg: String? = null
) {
    companion object {
        val INITIAL = NetworkState(Status.INITIAL)
        val SUCCESS = NetworkState(Status.SUCCESS)
        val LOADING = NetworkState(Status.LOADING)
        fun error(msg: String?) = NetworkState(Status.FAILED, msg)
    }
}

并将网络状态放入viewModel中。此外,在获取数据时,您必须更新viewModel中的状态,将其更改为LOADING。

class ViewModel ... {
  private val _networkState = MutableStateFlow(NetworkState.INITIAL)
    val networkState: StateFlow<NetworkState> = _networkState

fun getDataWithoffset(offset : Int){

        _networkState.value = NetworkState.LOADING

//get data from server and update values

}

然后在视图内部处理,如下所示:

@ExperimentalCoroutinesApi
@Composable
fun LatestNewsFeed(viewModel: NewsViewModel) {
    val state = viewModel.newsState.collectAsState()
    val netWorkstate = viewModel.networkState

if (netWorkstate.value == NetworkState.INITIAL) {
    viewModel.getDataWithoffset(0)
}
    val lastIndex = state.value.articles.lastIndex
    LazyColumnForIndexed(items = state.value.articles) { i, newsItem ->
        if (lastIndex == i) {
            onActive {
                viewModel.getDataWithoffset(lastIndex+1)
            }
        }
        NewsCard(newsItem) {
            viewModel.onSelectedNews(newsItem)
        }
    }
}
wn9m85ua

wn9m85ua3#

您可以将Paging library与compose一起使用。
例如

val customerList =dao.getAllCustomers().toLiveData(50)

其中DAO

@Query("SELECT * FROM customers ORDER BY name")
fun getAllCustomers():DataSource.Factory<Int, Customer>

但如果您的数据源来自房间数据库,则需要将其保存在单独的模块中
最后显示LiveData列表

@Composable
fun LiveDataCustomerListView(liveList:  LiveData<out List<Customer>>) {
    
    val list by liveList.observeAsState(initial =  emptyList<Customer>())
    AdapterList(data = list) { customer->

       Text("name:${customer.name}") 
    }
    
}

相关问题