在Flutter中,实现输入框一般使用TextField,通过设置它的属性给输入框和内部文字设置不同的样式。
Flutter 输入框实现简单例子
import 'package:flutter/material.dart';
class MyEditPage extends StatelessWidget {
const MyEditPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("My EditText"),
),
//body 是否延伸到底部控件
extendBody: true,
body: Column(
children: [
//Spacer创建一个可调整的空间隔,可用于调整Flex容器(如行或列)中窗口小部件之间的间距。
const Spacer(),
const Spacer(),
Container(
//通常用于给一个盒子的四边设置边距,用这个对象可以设置内边距。
margin: const EdgeInsets.all(10),
child: const Center(
child: TextField(
minLines: 1, //必须填1,输入内容才可居中,其他默认是左上对齐
maxLines: 10, //最多行数,大于1即可
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
//圆角
borderSide: BorderSide(width: 1, color: Colors.yellow)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
//圆角
borderSide: BorderSide(width: 1, color: Colors.yellow)),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
//圆角
borderSide: BorderSide(width: 1, color: Colors.yellow)),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
//圆角
borderSide: BorderSide(width: 1, color: Colors.yellow)),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
//圆角
borderSide: BorderSide(width: 1, color: Colors.yellow)),
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
),
),
))
],
),
);
}
}
下述代码可以抽出来:
OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)), //圆角
borderSide: BorderSide(width: 1, color: Colors.yellow))
static const border = OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)), //圆角
borderSide: BorderSide(width: 1, color: Colors.yellow));
class MyEditPage extends StatelessWidget {
const MyEditPage({super.key});
static const border = OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)), //圆角
borderSide: BorderSide(width: 1, color: Colors.yellow));
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("My EditText"),
),
//body 是否延伸到底部控件
extendBody: true,
body: Column(
children: [
//Spacer创建一个可调整的空间隔,可用于调整Flex容器(如行或列)中窗口小部件之间的间距。
const Spacer(),
const Spacer(),
Container(
//通常用于给一个盒子的四边设置边距,用这个对象可以设置内边距。
margin: const EdgeInsets.all(10),
child: const Center(
child: TextField(
minLines: 1, //必须填1,输入内容才可居中,其他默认是左上对齐
maxLines: 10, //最多行数,大于1即可
decoration: InputDecoration(
border: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
disabledBorder: border,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
),
),
))
],
),
);
}
OutlineInputBorder getBorder() {
OutlineInputBorder outlineInputBorder = const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)), //圆角
borderSide: BorderSide(width: 1, color: Colors.blue));
return outlineInputBorder;
}
}
TextField介绍
TextField 是 Material Design 文本字段。它允许用户使用硬件键盘或屏幕键盘输入文本。每当用户更改TextField 中的文本时,TextField 都会调用 onChanged 回调。如果用户完成在TextField 中的输入(例如,通过按下软键盘上的按钮),TextField 将调用 onSubmitted 回调。
const TextField({
super.key,
this.controller,
this.focusNode,
this.undoController,
this.decoration = const InputDecoration(),
TextInputType? keyboardType,
this.textInputAction,
this.textCapitalization = TextCapitalization.none,
this.style,
this.strutStyle,
this.textAlign = TextAlign.start,
this.textAlignVertical,
this.textDirection,
this.readOnly = false,
@Deprecated(
'Use `contextMenuBuilder` instead. '
'This feature was deprecated after v3.3.0-0.5.pre.',
)
this.toolbarOptions,
this.showCursor,
this.autofocus = false,
this.statesController,
this.obscuringCharacter = '•',
this.obscureText = false,
this.autocorrect = true,
SmartDashesType? smartDashesType,
SmartQuotesType? smartQuotesType,
this.enableSuggestions = true,
this.maxLines = 1,
this.minLines,
this.expands = false,
this.maxLength,
this.maxLengthEnforcement,
this.onChanged,
this.onEditingComplete,
this.onSubmitted,
this.onAppPrivateCommand,
this.inputFormatters,
this.enabled,
this.ignorePointers,
this.cursorWidth = 2.0,
this.cursorHeight,
this.cursorRadius,
this.cursorOpacityAnimates,
this.cursorColor,
this.cursorErrorColor,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start,
bool? enableInteractiveSelection,
this.selectionControls,
this.onTap,
this.onTapAlwaysCalled = false,
this.onTapOutside,
this.mouseCursor,
this.buildCounter,
this.scrollController,
this.scrollPhysics,
this.autofillHints = const <String>[],
this.contentInsertionConfiguration,
this.clipBehavior = Clip.hardEdge,
this.restorationId,
this.scribbleEnabled = true,
this.enableIMEPersonalizedLearning = true,
this.contextMenuBuilder = _defaultContextMenuBuilder,
this.canRequestFocus = true,
this.spellCheckConfiguration,
this.magnifierConfiguration,
})
获取TextField中信息
1.使用onChanged回调方法,将TextField当前的值保存在变量中。
class MyEditPage extends StatelessWidget {
const MyEditPage({super.key});
static const border = OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)), //圆角
borderSide: BorderSide(width: 1, color: Colors.yellow));
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("My EditText"),
),
//body 是否延伸到底部控件
extendBody: true,
body: Column(
children: [
//Spacer创建一个可调整的空间隔,可用于调整Flex容器(如行或列)中窗口小部件之间的间距。
const Spacer(),
const Spacer(),
Container(
//通常用于给一个盒子的四边设置边距,用这个对象可以设置内边距。
margin: const EdgeInsets.all(10),
child: Center(
child: TextField(
onChanged: (String value) {
print("value:"+value);
},
minLines: 1, //必须填1,输入内容才可居中,其他默认是左上对齐
maxLines: 10, //最多行数,大于1即可
decoration: InputDecoration(
border: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
disabledBorder: border,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
),
),
))
],
),
);
}
OutlineInputBorder getBorder() {
OutlineInputBorder outlineInputBorder = const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)), //圆角
borderSide: BorderSide(width: 1, color: Colors.blue));
return outlineInputBorder;
}
}
2024-09-03 11:45:37.758 5798-5832 flutter I value:1
2024-09-03 11:45:37.994 5798-5832 flutter I value:11
2024-09-03 11:45:38.437 5798-5832 flutter I value:115
2024-09-03 11:45:38.668 5798-5832 flutter I value:1155
2024-09-03 11:45:38.867 5798-5832 flutter I value:11555
2024-09-03 11:45:39.066 5798-5832 flutter I value:115555
2.TextEditingController 控制器监听和控制TextField的文本
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class TextFieldPageState extends State {
//文本框输入控制器
TextEditingController controller = TextEditingController();
//控制TextField焦点的获取与关闭
FocusNode focusNode = FocusNode();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("TextField 标题"),
actions: <Widget>[
FloatingActionButton(
child: Text(
"Click",
style: TextStyle(color: Colors.white),
),
onPressed: () {
//获取文本输入框内容
String inputText = controller.text;
print("文本输入框内容是:$inputText");
},
)
],
),
body: Center(
child: SizedBox(
width: 400,
height: 110,
child: Container(
color: Colors.white24,
padding: EdgeInsets.all(10),
alignment: Alignment(0, 0),
child: TextField(
controller: controller,
onChanged: (value) {
print("onChanged:$value");
},
),
),
),
),
);
}
@override
void initState() {
super.initState();
String preText = "";
//控制器,初始化的时候光标显示在文字后面
controller = TextEditingController.fromValue(TextEditingValue(
//用来设置初始化显示
text: preText,
selection: TextSelection.fromPosition(
//用来设置文本的位置
TextPosition(
affinity: TextAffinity.downstream, offset: preText.length))));
// 添加监听 当TextFeild 中内容发生变化 或者 焦点变动 都会触发回调
// onChanged 当TextFeild文本发生改变时才会回调
controller.addListener(() {
String currentStr = controller.text;
print("使用 Controller 监听 $currentStr");
});
}
}
class TextFieldHome extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return TextFieldPageState();
}
}
2024-09-03 14:32:20.094 23776-23959 flutter I 使用 Controller 监听 1
2024-09-03 14:32:20.280 23776-23959 flutter I 使用 Controller 监听 15
2024-09-03 14:32:20.449 23776-23959 flutter I 使用 Controller 监听 155
3.TextField回调onEditingComplete & onSubmitted
onEditingComplete: () {
print("onEditingComplete:" "编辑完成——>" + controller.text);
}
输入123点击回车:
2024-09-03 14:45:45.778 28502-28537 flutter I onEditingComplete:编辑完成——>123
onSubmitted: (value) {
print("onSubmitted:$value");
}
2024-09-03 14:45:45.779 28502-28537 flutter I onSubmitted:123
2024-09-03 14:45:49.374 28502-28537 flutter I onSubmitted:123
2024-09-03 14:49:16.016 28502-28537 flutter I onSubmitted:123
4.TextField焦点
TextField获得焦点表示TextField被激活并且任何来自键盘的输入都会被录入到获得焦点的TextField内。
4.1自动获得焦点
autofocus: true
child: TextField(
autofocus: true,
onChanged: (String value) {
print("value:" + value);
},
minLines: 1,
//必须填1,输入内容才可居中,其他默认是左上对齐
maxLines: 10,
//最多行数,大于1即可
decoration: InputDecoration(
border: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
disabledBorder: border,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
),
)
4.2TextField自定义焦点切换
import 'package:flutter/material.dart';
class MyCustomTextFieldPage extends StatelessWidget {
final nodeOne = FocusNode();
final nodeTwo = FocusNode();
MyCustomTextFieldPage({super.key});
static const border = OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)), //圆角
borderSide: BorderSide(width: 1, color: Colors.yellow));
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("My EditText TEST")),
extendBody: true,
body: Column(
children: [
const Spacer(),
const Spacer(),
Container(
margin: const EdgeInsets.all(10),
child: Center(
child: TextField(
autofocus: true,
focusNode: nodeOne,
minLines: 1,
//必须填1,输入内容才可居中,其他默认是左上对齐
maxLines: 10,
//最多行数,大于1即可
decoration: InputDecoration(
border: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
disabledBorder: border,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
)),
),
),
const Spacer(),
Container(
margin: const EdgeInsets.all(10),
child: Center(
child: TextField(
focusNode: nodeTwo,
minLines: 1,
//必须填1,输入内容才可居中,其他默认是左上对齐
maxLines: 10,
//最多行数,大于1即可
decoration: InputDecoration(
border: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
disabledBorder: border,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
)),
),
),
const Spacer(),
const Spacer(),
IconButton(
onPressed: () {
FocusScope.of(context).requestFocus(nodeTwo);
},
icon: Icon(Icons.accessible)),
const Spacer(),
const Spacer(),
],
),
);
}
}
上述代码实现自定义焦点切换
5.TextField键盘属性
TextField可以定制和键盘相关的属性 (TextInputType)
5.1.键盘类型
TextInputType
TextField(keyboardType: TextInputType.number)
/// All possible enum values.
static const List<TextInputType> values = <TextInputType>[
text, multiline, number, phone, datetime, emailAddress, url, visiblePassword, name, streetAddress, none,
];
5.2.键盘操作按钮
TextField的textInputAction可以更改键盘本身的操作按钮。
textInputAction: TextInputAction.send,
enum TextInputAction {
none,
unspecified,
done,
go,
search,
send,
next,
previous,
continueAction,
join,
route,
emergencyCall,
newline,
}
5.3文本大写
TextField可以对用户输入的文本进行大写化设置。
textCapitalization: TextCapitalization.characters
TextCapitalization.characters:所有字符都大写。
child: TextField(
textCapitalization: TextCapitalization.sentences,
textInputAction: TextInputAction.send,
keyboardType: TextInputType.text,
autofocus: true,
minLines: 1,
//必须填1,输入内容才可居中,其他默认是左上对齐
maxLines: 10,
//最多行数,大于1即可
decoration: InputDecoration(
border: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
disabledBorder: border,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
))
enum TextCapitalization {
/// Defaults to an uppercase keyboard for the first letter of each word.
///
/// Corresponds to `InputType.TYPE_TEXT_FLAG_CAP_WORDS` on Android, and
/// `UITextAutocapitalizationTypeWords` on iOS.
words,
/// Defaults to an uppercase keyboard for the first letter of each sentence.
///
/// Corresponds to `InputType.TYPE_TEXT_FLAG_CAP_SENTENCES` on Android, and
/// `UITextAutocapitalizationTypeSentences` on iOS.
sentences,
/// Defaults to an uppercase keyboard for each character.
///
/// Corresponds to `InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS` on Android, and
/// `UITextAutocapitalizationTypeAllCharacters` on iOS.
characters,
/// Defaults to a lowercase keyboard.
none,
}
6.文本对齐
TextAlign属性设置TextField内容对齐方式
textAlign: TextAlign.center
enum TextAlign {
left,
right,
center,
justify,
start,
end,
}
7.文本样式
style属性用来更改TextField文本的样式。 例如颜色,字体大小等。
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.w800),
8.光标样式
TextField可以自定义光标。 例如光标颜色,宽度和半径。
child: TextField(
cursorColor: Colors.red,
cursorRadius: Radius.circular(10.0),
cursorWidth: 5,)
9.控制最大字符数
maxLength: 4
设置maxLength后,TextField默认添加一个长度计数器。
10.TextField设置最大行数
maxLines: 10
如果只设置最大行数TextField会被撑起来。
11.隐藏文本内容
obscureText: true,
minLines: 1,
obscureText: true,
maxLines: 1
obscureText要生效的话,maxLines需要设置为1.
12.装饰TextField
decoration: InputDecoration(
hintText: "这是提示文案")
decoration: InputDecoration(
labelText: '这是LABEL文案')
13.图标
decoration: InputDecoration(
icon: Icon(Icons.alarm),)
decoration: InputDecoration(
prefixIcon: Icon(Icons.alarm),)
decoration: InputDecoration(
prefix: CircularProgressIndicator(),)
14.用hintStyle修改hint样式
hintStyle: TextStyle(fontWeight: FontWeight.w500, color: Colors.blue),
15.帮助性提示
帮助性提示会一直显示在输入框下部
decoration: InputDecoration(
icon: Icon(Icons.alarm),
helperText: 'help!')
16.使用decoration: null或者InputDecoration.collapsed可以去除默认的下划线
decoration: InputDecoration.collapsed(hintText: "")
17. 使用border给TextField设置边框
static const border = OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(width: 1, color: Colors.yellow));
decoration: InputDecoration(
border: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
disabledBorder: border,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.all(5),
)