Android Compose 记住影响其他记住更改

时间:2021-07-29 16:18:36

标签: android android-jetpack-compose

我有下一个层次结构:

  • 钱包详细信息屏幕
    • 钱包详情查看
      • 子钱包视图
      • DefaultOutlinedButton

1st remember domainsVisible 在 WalletDetailsS​​creen 中声明。回调会传播到 DefaultOutlinedButton 的 onClick。
第二个 remember copyToClipboardClicked 在 SubWalletView 中声明。

发生了什么:

  1. 用户打开屏幕。
  2. 用户首先点击复制按钮(SubWalletView)。 (第二次记住)
  3. 然后用户点击 DefaultOutlinedButton。第一个记忆改变了第二个记忆也改变了!

代码:

@Composable
fun WalletDetailsScreen(
    snackbarController: SnackbarController,
    wallet: Wallet,
    onNavIconClicked: () -> Unit
) {
    // CHANGING THIS REMEMBER CHANGES 2ND ONE (BUT ONLY IF 2ND WAS FIRED AT LEAST ONCE)
    val domainsVisible = rememberMutableStateOf(key = "domains_visible_btn", value = false)

        WalletDetailsView(
            snackbarController = snackbarController,
            wallet = wallet,
            domainsVisible = domainsVisible.value,
            domainsCount = 0
        ) {
            domainsVisible.toggle()
        }
}

@Composable
private fun WalletDetailsView(
    snackbarController: SnackbarController,
    wallet: Wallet,
    domainsVisible: Boolean,
    domainsCount: Int,
    onDomainsVisibilityClicked: () -> Unit
) {
        Column {
            wallet.subWallets.forEach { subWallet ->
                SubWalletView(snackbarController = snackbarController, subWallet = subWallet)
            }
            
            // 1st REMEMBER IS CHANGED HERE 
            DefaultOutlinedButton(text = text, onClick = onDomainsVisibilityClicked) 
        }
}

@Composable
private fun SubWalletView(
    snackbarController: SnackbarController,
    subWallet: SubWallet
) {
    // 2ND REMEMBER
    val copyToClipboardClicked = rememberMutableStateOf(key = "copy_btn", value = false)
    if (copyToClipboardClicked.value) {
        CopyToClipboard(text = subWallet.address)
    }

            // 2ND REMEMBER IS CHANGED HERE
            Box(
                modifier = Modifier
                    .clickable { copyToClipboardClicked.toggle() } 
                    .padding(start = 15.dp, top = 5.dp, bottom = 5.dp, end = 5.dp)
            ) {
                // just icon here
            }
}

帮助者:

@Composable
fun <T> rememberMutableStateOf(
    key: String,
    value: T,
    policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
) = remember(key) { mutableStateOf(value, policy) }

fun MutableState<Boolean>.toggle() {
    value = !value
}

我尝试添加要记住的键,但没有帮助。任何想法为什么改变一个记忆会影响另一个?这不应该发生。

1 个答案:

答案 0 :(得分:0)

我终于知道是怎么回事了。
第二个 remember 实际上没有改变。
但我依靠它来显示 shackbar:

    if (copyToClipboardClicked.value) {
        CopyToClipboard(text = subWallet.address)
        ShowSnackbar(...)
        copyToClipboardClicked.toggle() // <--- WE NEED THIS
    }

错过的部分是我需要关闭标志。我没有这样做,这就是为什么每次重新组合都会触发 if。