【问题标题】:How can I update remote data list when data updated?数据更新时如何更新远程数据列表?
【发布时间】:2023-02-16 10:33:40
【问题描述】:

  1. 在屏幕中选择
  2. 导航到 B 屏幕
  3. 在B屏编辑产品信息
  4. 按下保存按钮,更新成功后,导航至 A 屏幕
  5. A 屏幕显示更新列表

    屏幕

    sealed class Screen (
        val route: String
    ) {
        object List: Screen("product_list") //-->A Screen
        object EditProduct: Screen("edit_product") //-->B Screen
    }
    

    MainActivity onCreate 中的 NavHost

            NavHost(navController = navController, startDestination = Screen.Splash.route) {
                
                composable(route = Screen.List.route) { 
                    ListScreen()
                }
                composable(route = Screen.EditProduct.route) {
                    EditProductScreen()
                }
    

    A 是调出远程数据并代表列表的屏幕,B 包含从 A 中选择的产品的详细信息。

    在B输入产品信息后,我想更新A的列表,当我向上导航返回A时显示修改后的信息。

    遇到这种情况,我该如何处理呢?


    LaunchedEffect(true) {
        viewModel.eventFlow.collectLatest { event ->
            when(event) {
                is UiEvent.SaveTask -> {
                    //previousBackStackEntry?.savedStateHandle?.set<Boolean>("save_result", true)
                    onSave()
                }
            }
        }
    }
    

    当我调用 onSave() --navcontroller::popBackStack 时, 导航到屏幕,但列表未更新

【问题讨论】:

    标签: navigation android-jetpack-compose


    【解决方案1】:

    您可以将回调传递给您的EditProductScreen,并在该回调中调用navController.popBackStack()以及您的列表更新代码。

    @Composable
    fun EditProductScreen(onSave: () -> Unit) {
        Button(onClick = onSave) {
        }
    }
    
    composable(route = Screen.EditProduct.route) {
        EditProductScreen(
            onSave = {
                navController.popBackStack()
                // update your list
            }
        )
    }
    

    【讨论】:

    • 我尝试使用 popbackstack,但 A Screen 没有更新列表。
    • @PolarisNation 那么您应该添加您尝试执行此操作的代码。
    【解决方案2】:

    这是我处理从其他屏幕重新加载数据的解决方案。

    在主屏幕的 ViewModel 上,创建一个状态来存储重新加载地图。

    class MainViewModel() : ViewModel() {
    
        private val _reloadMap: MutableStateFlow<MutableMap<String, Boolean>> = MutableStateFlow(hashMapOf())
    
        val reloadMap: StateFlow<MutableMap<String, Boolean>> = _reloadMap
    
        fun triggerReload(key: String) {
            _reloadMap.value = reloadMap.value.apply {
                put(key, true)
            }
        }
    
        fun markReloaded(key: String) {
            _reloadMap.value = reloadMap.value.apply {
                put(key, false)
            }
        }
    }
    

    在定义了 NavHost 的 Composable 上声明 MainViewModel,并将此 ViewModel 传递给需要连接的 Composable

    val viewModel: MainViewModel = viewModel()
    composable(route = Screen.List.route) { 
        ListScreen(viewModel)
    }
    composable(route = Screen.EditProduct.route) {
        EditProductScreen(viewModel)
    }
    

    EditProductScreen调用triggerReload()保存数据时用一个key

    mainViewModel.triggerReload("list_screen")
    

    ListScreen收到reload key后收集reloadMap重新加载数据

    LaunchedEffect(key1 = Unit) {
        mainViewModel.reloadMap.asyncCollect(this) { map ->
            if (map.getOrDefault("list_screen", false)) {
                viewModel.reloadList()
                mainViewModel.markReloaded("list_screen")
            }
        }
    }
    
    
    // asyncCollect func:
    fun <T> SharedFlow<T>.asyncCollect(scope: CoroutineScope, onCollected: (T) -> Unit) {
        scope.launch {
            collectLatest {
                onCollected(it)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-09
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多