【问题标题】:Holding a List State in Horizontal Pager - Jetpack Compose在水平寻呼机中保持列表状态 - Jetpack Compose
【发布时间】:2021-09-22 15:19:39
【问题描述】:

我目前正在 JetPack Compose 中使用 Horizo​​ntal Pager 创建一个应用程序,如下所示

@ExperimentalAnimationApi
@ExperimentalPagerApi // HorizontalPager is experimental
@Composable
fun HorizontalPages(
    lstQuestions: List<CertQuestions>,
    lstOptions: List<CertAnswers>,
    mainDataViewModel: MainDataViewModel,
    pagerState: PagerState,
    modifier: Modifier = Modifier
) {
     HorizontalPager(
        state = pagerState,
        modifier = Modifier.fillMaxSize()
    ) { page ->
        val certQuestions = lstQuestions[page]
        val lstOptionsFiltered: List<CertAnswers> = lstOptions.filter { lstQuestions.map { certQuestions.question_id } .contains(it.question_id) }
        val lst: List<CertAnswers> =
            lstOptionsFiltered.filter { it.question_id == certQuestions.question_id }.toList()
            QueryCardPager(query = certQuestions, lstOptions = lst, mainDataViewModel= mainDataViewModel , pageNumber = page+1, pageCount = lstQuestions.size)
    }
}

上面的listQuestion基本上是我根据条件从数据库中检索出来的一个随机列表。

when (val result = mainDataViewModel.quState.collectAsState().value) {
    is QueryState.Error -> {
        Log.d("Error", "Error Occured")
    }
    is QueryState.Success -> {
        lstQuestions = result.queries

        lstQuestions = when (filter) {
            "pass" -> {
                lstQuestions.filter { it.knowAnswer }.shuffled()
            }
            "new" -> {
                lstQuestions.filter { !it.knowAnswer }.shuffled()
            }
            "random25" -> {
                lstQuestions.shuffled().take(25)
            }
            "random65" -> {
                lstQuestions.shuffled().take(65)
            }
            else -> {
                lstQuestions.shuffled()
            }
        }
    }
}

在卡片视图中,我正在调用 ViewModel 数据更新方法,它基本上将更新的布尔变量发送到 DB。

@ExperimentalAnimationApi
@Composable
fun QueryCardPager(query: CertQuestions,
                   lstOptions: List<CertAnswers>,
                   mainDataViewModel: MainDataViewModel,
                   pageNumber : Int,
                   pageCount : Int,
){
.
.
.
    IconButton(
        onClick = {
            mainDataViewModel.updateKnowAnswer(query.question_id, !query.knowAnswer)
        }
    ) {
        Icon(
            imageVector = if (query.knowAnswer) Icons.Filled.DoneAll
            else Icons.Filled.Done,
            contentDescription = null,
            tint = if (query.knowAnswer) Color.Blue else Color.Gray
        )
    }
}

视图模型

private val _quState = MutableStateFlow<QueryState>(QueryState.Loading)
private val _optState = MutableStateFlow<OptionsState>(OptionsState.Loading)

// UI collects from this StateFlow to get it"s state update
val quState = _quState.asStateFlow()
val optState = _optState.asStateFlow()

fun getQuestions() = viewModelScope.launch {

    try {
        certsRepository.getAllQuestions().distinctUntilChanged().collect(){ result->
            if(result.isEmpty()){
                _quState.value =QueryState.Empty
            }else
            {
                _quState.value = QueryState.Success(result)
                //questionsData.value = result
            }
        }
    }catch (e: Exception){
        _quState.value = QueryState.Error(exception = e)
    }
}

问题是在我调用 updateKnowAnswer 方法后,它可以工作一段时间。当它工作时,列表会再次刷新并加载一个新的随机列表。如何保存列表以及我是否以正确的方式调用更新方法。

【问题讨论】:

  • mainDataViewModel.quState 值从何而来?在您致电 updateKnowAnswer 后,此流程是否会更新?
  • @PhilipDukhov 我已经用 View Model 更新了这个问题。是的,它来自视图模型,它从数据库中获取数据。我相信只要 updateKnowAnswer 更新数据库中的值。流程正在刷新,带有新内容的寻呼机数据也在刷新。

标签: android-jetpack-compose


【解决方案1】:

您需要在 shuffle 之后保存 id 并在下次重复使用它们。我建议您也将此登录名移至视图模型,如下所示:

private val _filter = MutableStateFlow("pass")
val filter: Flow<String> = _filter

fun updateFilter(filter: String) {
    _filter.value = filter
}

private var savedRandomIds = mutableMapOf<String, List<QueryId>>()

val lstQuestions: Flow<List<Query>> = quState.combine(_filter) { result, filter ->
    when (result) {
        is QueryState.Error -> {
            Log.d("Error", "Error Occured")
            listOf()
        }
        is QueryState.Success -> {
            val savedIds = savedRandomIds[filter]
            if (savedIds != null) {
                result.queries.filter { savedIds.contains(it.id) }
            } else {
                when (filter) {
                    "pass" -> {
                        result.queries
                            .filter { it.knowAnswer }
                            .shuffled()
                    }
                    "new" -> {
                        result.queries.filter { !it.knowAnswer }.shuffled()
                    }
                    "random25" -> {
                        result.queries.shuffled().take(25)
                    }
                    "random65" -> {
                        result.queries.shuffled().take(65)
                    }
                    else -> {
                        result.queries.shuffled()
                    }
                }.also { shuffled ->
                    savedRandomIds[filter] = shuffled.map { it.id }
                }
            }
        }
    }
}

在您的可组合集合中收集lstQuestions 而不是quState

mainDataViewModel.lstQuestions.collectAsState(listOf())

【讨论】:

  • 这很好用。谢谢。
猜你喜欢
  • 2023-02-03
  • 2022-08-22
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多