"Jetpack Compose Series Learning" -7 TextField of Compose's Simple Control

Enter and modify text

TextField in Compose allows users to enter and modify text, just like EditText in Android. There are two TextField implementations: TextField and BasicTextField.

  1. TextField

TextField is a Material Design implementation, the default style is filled, and OutlinedTextField is an outline style. Let's first look at the use of TextField:

// TextField用法
val text = remember {
    mutableStateOf("你好")
}
TextField(
    value = text.value,
    onValueChange = {text.value = it},
    label = { Text("标签") }
)
复制代码

We know that passing the String value in State to the value in TextField, when text is entered in TextField, onValueChange will assign the value to State, trigger Compose reorganization when State changes, and update the control state, let's take a look at the effect :

image.png

Let's take another look at OutlinedTextField

Column {
    val text = remember {
        mutableStateOf("你好")
    }
    OutlinedTextField(
        value = text.value,
        onValueChange = {text.value = it},
        label = { Text("") }
    )
}
复制代码
  1. OutlinedTextField
Column {
    val text = remember {
        mutableStateOf("你好")
    }
    OutlinedTextField(
        value = text.value,
        onValueChange = {text.value = it},
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.Red)
            .padding(15.dp),
        label = { Text("标签") }
    )
}
复制代码

image.png

It can be seen that the usage of OutlinedTextField and TextField is basically the same, except that there is an outer border.

  1. BasicTextField

BasicTextField allows users to edit text through the soft keyboard or hard keyboard, but does not provide decorations such as prompts or placeholders. The usage is as follows:

Column {
    val text = remember {
        mutableStateOf("你好")
    }
    BasicTextField(
        value = text.value,
        onValueChange = {text.value = it}
    )
}
复制代码

image.png

The usage methods are similar, but they don't look so beautiful, but we can set them to be more beautiful through properties.

display style

The parameters of TextField and BasicTextField are basically the same. We can take TextField as an example to see the usage of some properties. Let's take a look at its source code:

@Composable
fun TextField(
    value: String, // 文字
    onValueChange: (String) -> Unit, // 监听输入
    modifier: Modifier = Modifier, // 修饰符
    enabled: Boolean = true, // 是否可点击
    readOnly: Boolean = false, // 是否只读
    textStyle: TextStyle = LocalTextStyle.current, // 文字样式
    label: @Composable (() -> Unit)? = null, // 显示在文本容器内的可选标签
    placeholder: @Composable (() -> Unit)? = null, // 占位符
    leadingIcon: @Composable (() -> Unit)? = null, // 文本容器开头的可选icon
    trailingIcon: @Composable (() -> Unit)? = null, // 文本容器结尾的可选icon
    isError: Boolean = false, // 指示文字的当前内容是否错误
    visualTransformation: VisualTransformation = VisualTransformation.None, // 转换输入value的可视表示形式
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default, // 软键盘配置项
    keyboardActions: KeyboardActions = KeyboardActions(), // 输入完成后的IME操作回调,如“回车发送”
    singleLine: Boolean = false, // 是否是单行显示
    maxLines: Int = Int.MAX_VALUE, // 最大行数
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, // 由组件发出的交互流
    shape: Shape =
        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize), // 文本容器的形状
    colors: TextFieldColors = TextFieldDefaults.textFieldColors() // 光标不同状态下文本颜色
) {
    // 省略...
}
复制代码

There are some parameters that we are already familiar with in Text. Let's pick a few commonly used parameters to understand their usage.

Column {
    val text = remember {
        mutableStateOf("你好")
    }
    TextField(
        value = text.value,
        onValueChange = {text.value = it},
        label = { Text("Enter text") },
        maxLines = 2,
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(15.dp).background(Color.Red)
    )
}
复制代码

image.png

We can only enter two lines of text at most, and the style of the text.

keyboard options

EditText in Android View sets the input type through inputType, and TextField through the keyboardOptions parameter, its type is KeyboardOptions, let's take a look at its source code:

@Immutable
class KeyboardOptions constructor(
    val capitalization: KeyboardCapitalization = KeyboardCapitalization.None,
    val autoCorrect: Boolean = true,
    val keyboardType: KeyboardType = KeyboardType.Text,
    val imeAction: ImeAction = ImeAction.Default
) {
    companion object {
        /**
         * 默认选项
         */
        val Default = KeyboardOptions()
    }
    // 省略...
}
复制代码

capitalization参数类型是KeyboardCapitalization,用来请求软键盘大写文本的选项。其默认值是KeyboardCapitalization.None。其它的类型有:

companion object {
    /**
     * 不自动大写文本
     */
    val None = KeyboardCapitalization(0)

    /**
     * 所有字符大写
     */
    val Characters = KeyboardCapitalization(1)

    /**
     * 每个单词的第一个字符大写
     */
    val Words = KeyboardCapitalization(2)

    /**
     * 每个句子的第一个字符大写
     */
    val Sentences = KeyboardCapitalization(3)
}
复制代码

autoCorrect参数类型是Boolean, 默认状态是true,是通知键盘是否启用自动更正,这里需要注意,autoCorrect仅适用于基于文本的keyboardType,如KeyboardType.Email、KeyboardType.Uri,不适用于KeyboardType.Number。

keyboardType参数类型为KeyboardType,是文本字段中使用的键盘类型,来看看有哪几种类型:

companion object {
    /**
     * 常规键盘的IME的键盘类型
     */
    val Text: KeyboardType = KeyboardType(1)

    /**
     * 能够输入ASCII字符的IME
     */
    val Ascii: KeyboardType = KeyboardType(2)

    /**
     * 输入数字类型的IME
     */
    val Number: KeyboardType = KeyboardType(3)

    /**
     * 输入电话号码的IME
     */
    val Phone: KeyboardType = KeyboardType(4)

    /**
     * 输入Uri的IME
     */
    val Uri: KeyboardType = KeyboardType(5)

    /**
     * 输入电子邮箱的IME
     */
    val Email: KeyboardType = KeyboardType(6)

    /**
     * 输入密码的IME
     */
    val Password: KeyboardType = KeyboardType(7)

    /**
     * 输入数字密码的IME
     */
    val NumberPassword: KeyboardType = KeyboardType(8)
}
复制代码

开发中可以根据对应的业务去设置对应的输入类型。

imeAction参数类型是ImeAction,默认是ImeAction.Default,表示键盘会指定IME操作,并且可能会在键盘上显示特定的图标,如指定了ImeAction.Search,则可能会显示一个搜索图标,我们来看看ImeAction的源码,其伴生对象里定义了几种ImeAction类型:

companion object {
    /**
     * 默认,让键盘来决定操作
     */
    val Default: ImeAction = ImeAction(1)

    /**
     * 不执行任何操作,默认为换行的动作
     */
    val None: ImeAction = ImeAction(0)

    /**
     * 表示用户想转到输入的文本目标,即访问URL
     */
    val Go: ImeAction = ImeAction(2)

    /**
     * 表示用户执行搜索,即网络搜索查询
     */
    val Search: ImeAction = ImeAction(3)

    /**
     * 用户要在输入中发送文本,即SMS
     */
    val Send: ImeAction = ImeAction(4)

    /**
     * 用户想返回先前的输入,即返回表格中的先前字段
     */
    val Previous: ImeAction = ImeAction(5)

    /**
     * 用户已完成当前输入,并且想要移至下一个字段
     */
    val Next: ImeAction = ImeAction(6)

    /**
     * 用户已完成输入操作,现在应该发生某种终结行为
     */
    val Done: ImeAction = ImeAction(7)
}
复制代码

同KeyboardCapitalization和KeyboardType一样,在里面伴生对象中定义了几种类型,可以根据具体业务需求,使用对应的类型。

我们看一个例子:

Column {
    val text = remember {
        mutableStateOf("你好")
    }
    TextField(
        value = text.value,
        onValueChange = {text.value = it},
        label = { Text("Enter text") },
        keyboardOptions = KeyboardOptions(
            capitalization = KeyboardCapitalization.Characters, // 全部字符大写
            keyboardType = KeyboardType.Email, // 输入email
            autoCorrect = true, // 自动纠正
            imeAction = ImeAction.Search // IME动作设置为搜索
        ),
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(15.dp).background(Color.Red)
    )
}
复制代码

我们添加了KeyboardOptions,设置全部字符大写,键盘类型是KeyboardType.Email,并开启了自动更正,IME动作设置为ImeAction.Search,运行结果如图:

image.png

那么我们如何监听ImeAction并执行呢?就是KeyboardActions参数,里面有几种类型:

class KeyboardActions(
    /**
     * 用户触发ImeAction.Done操作时,执行该命令
     */
    val onDone: (KeyboardActionScope.() -> Unit)? = null,

    /**
     * 用户触发ImeAction.Go操作时,执行该命令
     */
    val onGo: (KeyboardActionScope.() -> Unit)? = null,

    /**
     * 用户触发ImeAction.Next操作时,执行该命令,空值表示应执行默认实现
     */
    val onNext: (KeyboardActionScope.() -> Unit)? = null,

    /**
     * 用户触发ImeAction.Previous操作时,执行该命令,空值表示应执行默认实现
     */
    val onPrevious: (KeyboardActionScope.() -> Unit)? = null,

    /**
     * 用户触发ImeAction.Search操作时,执行该命令
     */
    val onSearch: (KeyboardActionScope.() -> Unit)? = null,

    /**
     * 用户触发ImeAction.Send操作时,执行该命令
     */
    val onSend: (KeyboardActionScope.() -> Unit)? = null
) {
    companion object {
        /**
         * 不指定任何操作
         */
        val Default: KeyboardActions = KeyboardActions()
    }
}
复制代码

我们可以看到KeyboardActions是一个普通类,在构造方法中有6个参数,分别和ImeAction中的6个类型一一对应,所以如果设置了ImeAction,就需要实现对应的KeyboardActions来执行对应的操作。我们在上面的代码基础上添加KeyboardActions的代码:

Column {
    val context = LocalContext.current
    val text = remember {
        mutableStateOf("你好")
    }
    TextField(
        value = text.value,
        onValueChange = {text.value = it},
        label = { Text("Enter text") },
        keyboardOptions = KeyboardOptions(
            capitalization = KeyboardCapitalization.Characters, // 全部字符大写
            keyboardType = KeyboardType.Email, // 输入email
            autoCorrect = true, // 自动纠正
            imeAction = ImeAction.Search // IME动作设置为搜索
        ),
        keyboardActions = KeyboardActions(
            onSearch = {
                Toast.makeText(context, "点击了Search", Toast.LENGTH_LONG).show()
            }
        ),
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(15.dp).background(Color.Red)
    )
}
复制代码

点击后看效果:

image.png

We saw that the toast popped up, and we obtained the context context through LocalContext.current. You can also obtain the Context for use in the future. We will continue to learn other controls in the future. The relevant code has been uploaded to github github.com/Licarey/com… , please like it.

Guess you like

Origin juejin.im/post/7079265116306276359