Jetpack Compose 使用 Remember() 进行 LazyColumn 重组

Cla*_*tle 6 android kotlin android-jetpack-compose

我一直在尝试 Jetpack Compose 并遇到了一些带有列表LazyColumnremember().

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp{
                MyScreen()
            }
        }
    }
}

@Composable
fun MyApp(content: @Composable () -> Unit){
    ComposeTestTheme {
        // A surface container using the 'background' color from the theme
        Surface(color = MaterialTheme.colors.background) {
            content()
        }
    }
}

@Composable
fun MyScreen( names: List<String> = List(1000) {"Poofy #$it"}) {
    NameList( names, Modifier.fillMaxHeight())
}

@Composable
fun NameList( names: List<String>, modifier: Modifier = Modifier ){
    LazyColumn( modifier = modifier ){
        items( items = names ) { name ->
            val counter = remember{ mutableStateOf(0) }

            Row(){
                Text(text = "Hello $name")
                Counter(
                    count = counter.value,
                    updateCount = { newCount -> counter.value = newCount } )
            }
            Divider(color = Color.Black)
        }
    }
}

@Composable
fun Counter(count: Int, updateCount: (Int) -> Unit) {
    Button( onClick = {updateCount(count+1)} ){
        Text("Clicked $count times")
    }
}
Run Code Online (Sandbox Code Playgroud)

该程序运行并创建一个 1000 行的列表,其中每行显示“Hello Poofy #N”,后跟一个显示“Clicked N times”的按钮。

一切正常,但如果我单击一个按钮来更新其计数,则当它滚动到屏幕外并重新打开时,该计数将不会保留。

“回收LazyColumn”重新组合行和计数。在上面的示例中,计数器被吊起,NameList()但我已经尝试将其未吊起Counter()。两者都不起作用。

记住计数的正确方法是什么?我必须将它存储在活动中的数组中吗?

Phi*_*hov 5

的表示items被回收,并且新的indexremember被重置。这是预期的行为,您不应期望该值持续存在。

您不需要将其保留在 Activity 中,只需将其移出LazyColumn. 例如,您可以将其存储在可变状态列表中,如下所示:

val counters = remember { names.map { 0 }.toMutableStateList() }
LazyColumn( modifier = modifier ){
    itemsIndexed(items = names) { i, name ->
        Row(){
            Text(text = "Hello $name")
            Counter(
                count = counters[i],
                updateCount = { newCount -> counters[i] = newCount } )
        }
        Divider(color = Color.Black)
    }
}
Run Code Online (Sandbox Code Playgroud)

或者在可变状态图中:

val counters = remember { mutableStateMapOf<Int, Int>() }
LazyColumn( modifier = modifier ){
    itemsIndexed(items = names) { i, name ->
        Row(){
            Text(text = "Hello $name")
            Counter(
                count = counters[i] ?: 0,
                updateCount = { newCount -> counters[i] = newCount } )
        }
        Divider(color = Color.Black)
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,remember当屏幕旋转时也会重置,请考虑使用rememberSaveable而不是将数据存储在视图模型中。

在文档中阅读有关 Compose 中状态的更多信息