@ComposablefunEditNumberField( title:String,//标题 value:String,//要显示的当前值 onValueChange:(String)->Unit,//一个接受 String 值作为输入且没有返回值的函数,用作传入 TextField 可组合项的 onValueChange 回调。 keyboardOptions: KeyboardOptions, modifier: Modifier= Modifier){ TextField( value = value,//value 形参是一个文本框,用于显示您在此处传递的字符串值。 onValueChange = onValueChange,//是用户在文本框中输入文本时触发的 lambda 回调 label = {Text(title)}, singleLine = true,//单行显示 //keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),//将键盘类型设置为数字键盘即可输入数字 keyboardOptions = keyboardOptions, modifier=modifier )}
EditNumberField("标题2",amountInpu2,{amountInpu2=it}, keyboardOptions = KeyboardOptions.Default.copy( keyboardType = KeyboardType.Number, imeAction = ImeAction.Done ), modifier = Modifier .padding(12.dp) .fillMaxWidth())
那下面是啰嗦版带大家一步步实现对应整体功能,主要是对之前有些知识点的一些补充或者说一些重复动作加深印象,也有一些编程的小技巧。这里借助 TextField 可组合函数实现效果。本节我们换一个新的写法,不再一次次往主函数里面添加控件,显得主程序函数累赘冗长。这里的思路就是,将各个模块进行“封装”,第一是代码易于理解,第二是后续可以复用,减少代码冗余。那首先我们先新增一个函数放置本次我们需要实现的组合控件,效果如下:@ComposablefunEditNumberField(modifier: Modifier= Modifier){ TextField( value = "",//value 形参是一个文本框,用于显示您在此处传递的字符串值。 onValueChange = {},//是用户在文本框中输入文本时触发的 lambda 回调 modifier=modifier )}
然后在主程序入口进行调用,其效果如下(这里我是懒得重新新建项目费时间,还是在原有项目上做,大家如果觉得看着累或者需要其他效果,自己可以新建工程,是一样的):多嘴讲一句,有的朋友还不太理解为什么要用number来实现输入的保存,这里可以直接启动项目看看。在模拟器中运行该应用,尝试输入其他值。硬编码状态保持不变,因为 TextField可组合项不会自行更新。当value其属性值更改时,它才会更新,因此,我们需要新增一个变量,并赋值给value,当变量变化的时候,就会通知到当value,Compose 会使用新状态重新执行受影响的可组合函数,从而创建更新后的界面。(这一过程称为“重组”)。我们继续,给输入框添加变量(amoutInput)并设置成可被Compose 识别更新:@ComposablefunEditNumberField(modifier: Modifier= Modifier){ var amountInput by remember { mutableStateOf("") } TextField( value = amountInput,//value 形参是一个文本框,用于显示您在此处传递的字符串值。 onValueChange = {amountInput=it},//是用户在文本框中输入文本时触发的 lambda 回调 modifier=modifier )}
这时候,我们就可以在输入框输入内容,并看到你输入的值了。(以上是原有知识点细化讲解)singleLine = true,//单行显示keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),//将键盘类型设置为数字键盘即可输入数字
这里的意思就是,如果你需要在我们定义的EditNumberField函数外使用EditNumberField内部的参数,就需要进行状态提升。
那代码上的修改就是将内部参数改为外部“提供”:
@ComposablefunEditNumberField( value:String,//要显示的当前值 onValueChange:(String)->Unit,//一个接受 String 值作为输入且没有返回值的函数,用作传入 TextField 可组合项的 onValueChange 回调。 modifier: Modifier= Modifier){ var amountInput by remember { mutableStateOf("") }//后续放另一个地方 TextField( value = value,//value 形参是一个文本框,用于显示您在此处传递的字符串值。 onValueChange = onValueChange,//是用户在文本框中输入文本时触发的 lambda 回调 label = {Text("这是标题:")}, singleLine = true,//单行显示 keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),//将键盘类型设置为数字键盘即可输入数字 modifier=modifier )}
同时要将参数放在最外的地方进行传入:
同时补充使用EditNumberField函数的地方:
EditNumberField(amountInput,{amountInput=it})
这样的话,我们就可以在外部使用输入值了。例如在上图所示的DiceWithButtonAndImage函数中。(常用于将输入值进行计算,然后显示在其他控件上)
我们还可以将这个控件做出可以复用的模式,就是将标题也作为函数输入:需要注意的是,如果我们传入的是字符串资源,就需要在参数前加一个定义:label = { Text(stringResource(title)) }
这里我们先不加字符串资源传入,然后我们还可以做一些布局的装饰: modifier = Modifier .padding(12.dp) .fillMaxWidth()
@ComposablefunEditNumberField( title:String,//标题 value:String,//要显示的当前值 onValueChange:(String)->Unit,//一个接受 String 值作为输入且没有返回值的函数,用作传入 TextField 可组合项的 onValueChange 回调。 keyboardOptions: KeyboardOptions, modifier: Modifier= Modifier){ TextField( value = value,//value 形参是一个文本框,用于显示您在此处传递的字符串值。 onValueChange = onValueChange,//是用户在文本框中输入文本时触发的 lambda 回调 label = {Text(title)}, singleLine = true,//单行显示 //keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),//将键盘类型设置为数字键盘即可输入数字 keyboardOptions = keyboardOptions, modifier=modifier )}
keyboardOptions = KeyboardOptions.Default.copy( keyboardType = KeyboardType.Number, imeAction = ImeAction.Next ),
这里说明下:后面那个执行的效果是关闭键盘,因为没有绑定其他的内容。