繁体   English   中英

Jetpack Compose - 在 Accompanist HorizontalPager 中延迟加载数据

[英]Jetpack Compose - Lazy loading of data in Accompanist HorizontalPager

这个问题非常简单,我不知道为什么以前没有人问过。

我必须从数据库中查询大量数据,然后在HorizontalPager中一一显示。 如果我一次加载所有数据,在编写 Horizo HorizontalPager之前,加载时间太长,用户必须看到CircularProgressIndicator太长时间。

我只想加载对用户可见的HorizontalPager页面的数据。 所以它应该像这样 go :

  • 在 index = 0 时,仅加载第 0 页的数据,并在加载时显示CircularProgressIndicator
  • 在 index = 1 时,仅加载第 1 页的数据,并在加载时显示CircularProgressIndicator

等等。

我怎样才能做到这一点?

这是我写的不能正常工作的内容:

val map by viewModel.statementWithTransMap.collectAsStateWithLifecycle()

HorizontalPager(
    modifier = Modifier.fillMaxSize(),
    state = horizontalPagerState,
    count = statementIds.size
) { index ->

    LaunchedEffect(Unit) {
        val id = statementIds[index]
        viewModel.loadStatementByStatementId(index, id)
    }

    val item = map[index]

    if (item == null) {
        Box(modifier = Modifier.fillMaxSize()) {
            CircularProgressIndicator(
                modifier = Modifier.align(Alignment.Center)
            )
        }
        return@HorizontalPager
    }

    Page(item)
}

我在视图 model 中的相关代码是:

fun loadStatementByStatementId(index: Int, statementId: Int) {

    viewModelScope.launch {
        getStatementsWithTranslationByStatementIdUseCase(statementId).collect {

            loadedStatements[index] = it
            _statementWithTransMap.value = loadedStatements
        }
    }
}

我建议使用 androidx 分页,但如果你不想这样做,这样的东西应该可以工作。 为简单起见,我将其全部放在撰写代码中,但最好在 ViewModel 或类似的东西中处理加载。

@Composable fun MyPager(db: Database) {
    val loadedData = remember {
        mutableStateMapOf<Int, Item>()
    }
    HorizontalPager(count = 100) { index ->
        LaunchedEffect(Unit) {
            if (loadedData[index] == null) {
                loadedData[index] = db.getItem(index)
            }
        }

        val item = loadedData[index]
        if (item == null) {
            CircularProgressIndicator()
        } else {
            ItemContent(item)
        }
    }
}

根据有问题的代码进行编辑:好的,假设loadedStatementsMutableMap并且_statementWithTransMapStateFlow ,我认为问题就在这里:

loadedStatements[index] = it
_statementWithTransMap.value = loadedStatements

You update the mutable map and set it to the StateFlow, but the same map was already the value of that StateFlow and it doesn't emit when new value is the same (it doesn't care about the content of the map, the object是同样的)。 您必须创建一个新的 map,如下所示:

loadedStatements = loadedStatements.toMutableMap()
loadedStatements[index] = it
_statementWithTransMap.value = loadedStatements

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM