【Jetpack Compose基础语法学与练】第6课 TextField文本输入,字符串状态与输入交互

前言

上一课学习了状态提升,掌握单向数据流:父传数据、子传事件,抽离可复用无状态组件。

本课学习文本输入框 TextField ,处理字符串类型状态,实现用户输入实时绑定。

核心要点:文本输入属于高频可变状态,理解 mutableStateOf 字符串状态、输入值双向绑定,掌握基础输入框。

前置:完成1~5课,掌握remember、状态提升、基础布局

一、完整可运行示例源码

kotlin 复制代码
  
package com.example.composefirst

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

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

@Composable
fun TextFieldDemoPage() {
    // 字符串状态,初始为空字符串
    var inputText by remember { mutableStateOf("") }

    Column(modifier = Modifier.padding(20.dp)) {
        TextField(
            value = inputText,
            onValueChange = { newValue ->
                inputText = newValue
            },
            label = { Text("请输入内容") }
        )

        Spacer(modifier = Modifier.height(16.dp))
        Text(text = "你输入的内容:$inputText")

        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { inputText = "" }) {
            Text("清空输入")
        }
    }
}

@Preview
@Composable
fun TextFieldPreview() {
    TextFieldDemoPage()
}
 

二、逐行代码解读

  1. var inputText by remember { mutableStateOf("") }
    字符串状态,使用 mutableStateOf ,可以存放任意类型(字符串、对象等)。

之前数字我们用 mutableIntStateOf ,字符串没有专用简写,通用使用 mutableStateOf 。

remember 保证重组时不会丢失输入内容。

  1. TextField核心两个参数
kotlin 复制代码
  
TextField(
    value = inputText,
    onValueChange = { newValue -> inputText = newValue }
)
 
  • value :输入框当前显示的值,来自状态变量,单向数据源;
  • onValueChange :用户打字时不断回调,参数 newValue 是用户最新输入文本;
    我们在回调里把新值赋值给 inputText ,实现双向绑定效果。

底层原理:不是真正的双向绑定。用户输入 → onValueChange修改状态 → 状态改变触发重组 → value更新到输入框。

  1. label = { Text("请输入内容") }
    悬浮提示文字,Material3规范,输入框未输入时淡色提示,点击输入后上浮。
  2. 清空按钮逻辑
    点击按钮直接把 inputText = "" ,状态清空,自动重组,输入框内容同步清空。
    体现Compose核心:修改状态,UI自动同步。

三、拓展:抽成无状态组件(复用+状态提升)

真实开发,输入框组件抽离,状态放在父组件:

kotlin 复制代码
  
@Composable
fun TextFieldDemoPage() {
    var inputText by remember { mutableStateOf("") }
    Column(modifier = Modifier.padding(20.dp)) {
        InputField(
            value = inputText,
            onValueChange = { inputText = it }
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text("输入内容:$inputText")
    }
}

// 无状态输入框子组件
@Composable
fun InputField(value: String, onValueChange: (String) -> Unit) {
    TextField(
        value = value,
        onValueChange = onValueChange,
        label = { Text("请输入内容") }
    )
}
 

解读:子组件 InputField 没有remember,只接收value和回调,符合状态提升思想,多处页面可以复用这个输入框。

四、综合练习题

填空题

  1. 存储字符串类型状态,使用 remember 配合________。
  2. TextField中,________参数代表输入框当前展示的文本。
  3. 用户输入字符时,________回调会持续返回最新输入字符串。

答案与解析

  1. mutableStateOf ;解析:mutableStateOf是通用状态,字符串、自定义对象都可以使用。整型有专用mutableIntStateOf。
  2. value ;解析:输入框显示内容由value状态驱动。
  3. onValueChange ;解析:用户每输入、删除字符,都会触发该回调,带回最新文本。

判断题

  1. TextField不需要onValueChange,只写value就可以正常输入文字。()

答案:错误。理由:value是只读展示。不写onValueChange,无法更新状态,输入框会无法输入。

  1. mutableStateOf可以存放字符串,也可以存放自定义数据类对象。()

答案:正确。理由:mutableStateOf是通用泛型状态,支持任意类型。

  1. 状态提升后的输入框子组件,内部依然可以写remember保存输入文本。()

答案:错误。理由:状态提升方案,子组件为无状态组件,状态统一由父组件管理。

简答题

  1. Compose的TextField,是真正双向绑定吗?简述工作流程。

参考答案:

不是传统意义双向绑定。用户输入文字触发onValueChange,修改上层状态;状态变更触发重组,把新value渲染到输入框。本质还是单向数据流。

代码实操题

改造代码:增加判断,如果输入文本超过10个字,在下方提示「文字过长」,否则提示「输入正常」。写出完整TextFieldDemoPage。参考答案

kotlin 复制代码
  
@Composable
fun TextFieldDemoPage() {
    var inputText by remember { mutableStateOf("") }

    Column(modifier = Modifier.padding(20.dp)) {
        TextField(
            value = inputText,
            onValueChange = { inputText = it },
            label = { Text("请输入内容") }
        )
        Spacer(modifier = Modifier.height(16.dp))

        if(inputText.length > 10){
            Text("文字过长")
        }else{
            Text("输入正常")
        }
    }
}
 

解析:读取状态字符串长度,利用if条件渲染,状态变化自动刷新提示文本。

五、本课小结

  1. mutableStateOf 通用状态,适合字符串、对象;
  2. TextField依靠 value + onValueChange 完成输入交互;
  3. 可以把输入框抽为无状态组件,使用状态提升;
  4. 用户输入修改状态,状态驱动界面刷新。

下一课:if条件渲染 + 列表基础(LazyColumn)。

相关推荐
不要喷香水8 小时前
00-总览与架构
kotlin·app·档案管理
冬奇Lab8 小时前
DeepSeek Harness 系列(10):写一个完整的 dsh 插件——从需求到上线
人工智能·学习·开源
边境悍匪8 小时前
蜗牛学苑 Java 智能体学习 Day44|Vue 前端项目搭建 思维导图复盘
java·开发语言·spring boot·学习·阿里云
彧azz8 小时前
Java学习记录:判断语句
java·笔记·学习·算法
hai_android8 小时前
Android 组件化开发实践
android·java·kotlin
光影少年9 小时前
setImmediate 和 setTimeout(0) 的区别
android·前端·react.js·ios·前端框架
M78佐菲9 小时前
ARM学习笔记(四)
linux·arm开发·笔记·嵌入式硬件·学习
昌原的儿子LEO9 小时前
i.MX6ULL 裸机开发 C 语言驱动与 BSP 工程管理学习总结
linux·arm开发·学习
kkkkkkkkkk_Z9 小时前
单片机|学习日记:单片机底层架构与寄存器操作全解析
linux·笔记·单片机·学习·51单片机
逐辰十七10 小时前
2023级河海大学自动化计算机控制考试题目
学习