4. 状态提升

任务说明

在 Compose 中,子组件内部持有的状态无法被兄弟组件访问。本案例将输入框的文本状态提升到父组件,使两个子组件(文本输入框与文本展示区)共享同一份状态,实现输入实时回显。

核心实现

import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

// 父组件:持有状态并传递给子组件
@Composable
fun ParentScreen() {
    // 状态提升到父组件
    var text by remember { mutableStateOf("") }

    Column(
        modifier = Modifier.fillMaxSize().padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text(
            text = "状态提升示例",
            style = MaterialTheme.typography.headlineSmall
        )

        // 子组件1:输入框,接收状态与回调
        TextInputChild(
            value = text,
            onValueChange = { text = it }
        )

        // 子组件2:展示区,只读取状态
        TextDisplayChild(text = text)
    }
}

// 子组件1:输入框(无内部状态)
@Composable
fun TextInputChild(
    value: String,
    onValueChange: (String) -> Unit
) {
    OutlinedTextField(
        value = value,
        onValueChange = onValueChange,
        label = { Text("请输入内容") },
        singleLine = true,
        modifier = Modifier.fillMaxWidth()
    )
}

// 子组件2:文本展示(只读状态)
@Composable
fun TextDisplayChild(text: String) {
    Card(
        modifier = Modifier.fillMaxWidth()
    ) {
        Text(
            text = if (text.isEmpty()) "等待输入..." else "当前输入:$text",
            fontSize = 18.sp,
            modifier = Modifier.padding(16.dp)
        )
    }
}

状态流向说明

父组件通过 remember 创建唯一状态源 text,将值传给输入框子组件,同时传入更新回调;输入框触发 onValueChange 时更新父组件状态,父组件重组并将新值传给展示子组件。两个子组件本身不持有状态,只通过参数与回调与父组件通信,实现单向数据流。

落地与验证

在 Android 项目中创建上述 Composable 函数,并在 setContent 中调用 ParentScreen()。运行应用后,在输入框中键入任意字符,下方卡片中的文本应实时同步显示相同内容;清空输入框时,卡片显示“等待输入...”。若输入与展示内容一致且无延迟,则说明状态提升生效,两个子组件成功共享了父组件持有的状态。

父组件 ParentScreen var text by remember { mutableStateOf("") } 状态 text 唯一数据源 子组件1:输入框 TextInputChild value: String onValueChange: (String) -> Unit 子组件2:展示区 TextDisplayChild text: String(只读) 显示当前输入内容 value text onValueChange 状态向下传递(参数) 事件向上回调