前言
从本文我们就开始介绍具体的 Widget了,先介绍文本框、图片、输入框和表单。
1. 文本框--Text 和 RichText
Text
- 作用:显示文本的 Widget。
- 使用:
(1)必选参数 data:Text 的内容
Text("Hello Flutter");// Text 里传入要显示的文字
(2)可选参数 TextStyle:用来定义 Text 显示的样式,如颜色、大小、背景色等
Text(
"Hello Flutter",
style: TextStyle(
color: Colors.red,
fontSize: 20.0,
background: new Paint()..color = Colors.yellow,
),
)
- 代码示例:
import 'package:flutter/material.dart';
void main() => runApp(TextWidget());
class TextWidget extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
theme: ThemeData(
primaryColor: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text("Flutter UI基础Widget -- 文本")),
body: Text("Hello Flutter",
style: TextStyle(
color: Colors.red,
fontSize: 20.0,
background: new Paint()..color = Colors.yellow,
),)
),
);
}
}
-
运行结果:
Text 的其他参数
看一下 Text 的构造函数:
class Text extends StatelessWidget {
const Text(this.data, {
Key key, // 选填参数,Key类型,Widget的标识,
this.style, // 选填参数,TextStyle类型,文本样式
this.strutStyle, // 选填参数,StrutStyle类型,设置每行的最小行高
this.textAlign, // 选填参数,TextAlign类型,文本的对齐方式
this.textDirection, // 选填参数,TextDirection类型,文字方向
this.locale, // 选填参数,Local类型,用于选择用户语言和格式设置首选项的标识符
this.softWrap, // 选填参数,bool类型,是否支持软换行符,如果是 false 的话,这个文本只有一行,水平方向是无限的
this.overflow, // 选填参数,TextOverflow类型,文本的截断方式
this.textScaleFactor, // 选填参数,double类型,代表文本相对于当前字体大小的缩放因子,默认值为1.0
this.maxLines, // 选填参数,int类型,显示的最大行数
this.semanticsLabel, // 选填参数,String类型,给文本加上一个语义标签(用不到)
}) : assert(data != null),
textSpan = null,
super(key: key);
...
}
(1)textAlign:
文本的对齐方式,有六种:
TextAlign.left:左对齐
TextAlign.right:右对齐
TextAlign.center:居中对齐
TextAlign.start:从文字开始的那个方向对齐,如果文字方向从左到右,就左对齐,否则是右对齐
TextAlign.end:从文字开始的相反方向对齐,如果文字方向从左到右,就右对齐,否则是左对齐
TextAlign.justify
(2)textDirection:
文字方向,有两种:
TextDirection.ltr:文字方向从左到右
TextDirection. rtl:文字方向从右到左
(3)overflow:
文本的截断方式,有三种:
TextOverflow.ellipsis:多余文本截断后以省略符“...”表示
TextOverflow.clip:剪切多余文本,多余文本不显示
TextOverflow.fade:将多余的文本设为透明
- TextStyle 的构造参数
class TextStyle extends Diagnosticable {
const TextStyle({
this.inherit = true, // 可选,类型 bool,是否继承父 Text 的样式,默认为 true,如果为 false,且样式没有设置具体的值,则采用默认值:白色、大小 10px、sans-serif 字体
this.color, // 可选,类型 Color,文字的颜色
this.fontSize, // 可选,类型 Color,文字的大小
this.fontWeight, // 可选,类型 FontWeight,字体粗细
this.fontStyle, // 可选,类型 FontStyle,是否在字体中倾斜字形
this.letterSpacing, // 可选,类型 double,字母之间的间隔
this.wordSpacing, // 可选,类型 double,字母之间的间隔
this.textBaseline, // 可选,类型 TextBaseLine,用于对齐文本的水平线
this.height, // 可选,类型 double,文本的高度,但它并不是一个绝对值,而是一个因子,具体的行高等于 fontSize * height
this.locale, // 可选,类型 Locale,用于选择用户语言和格式设置首选项的标识符
this.foreground, // 可选,类型 Paint,文本的前景色
this.background, // 可选,类型 Paint,文本的背景色
this.shadows, // 可选,类型 List<ui.Shadow>,在文本下方绘制阴影
this.decoration, // 可选,类型 TextDecoration,文本的线条
this.decorationColor, // 可选,类型 Color,TextDecoration 线条的颜色
this.decorationStyle, // 可选,类型 TextDecorationStyle,TextDecoration 线条的样式
this.debugLabel, // 可选,类型 String,文本样式的描述
String fontFamily, // 可选,类型 String,用于设置使用那种自定义字体
List<String> fontFamilyFallback, // 可选,类型 String,字体列表,当前面的字体找不到时,会在这个列表里依次查找
String package, // 可选,类型 String
}) : fontFamily = package == null ? fontFamily : 'packages/$package/$fontFamily',
_fontFamilyFallback = fontFamilyFallback,
_package = package,
assert(inherit != null),
assert(color == null || foreground == null, _kColorForegroundWarning);
...
}
RichText
- 作用:可以显示多种样式的富文本Text。
- 代码示例:
import 'package:flutter/material.dart';
void main() => runApp(RichTextWidget());
class RichTextWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
theme: ThemeData(
primaryColor: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text("Flutter UI基础Widget -- 文本")),
body: RichText(
text: TextSpan(children: [
TextSpan(text: "Hello", style: TextStyle(color: Colors.blue)),
TextSpan(text: "Flutter", style: TextStyle(color: Colors.red))
]),
)),
);
}
}
-
运行结果:
- RichText 必选参数:TextSpan
如果需要对一个 Text 内容的不同部分按照不同的样式显示,这时就可以使用 TextSpan,它代表文本的一个片段,然后把不同的 TextSpan 组合起来。
TextSpan 的构造函数及参数说明:
class TextSpan extends DiagnosticableTree {
const TextSpan({
this.style, // 可选,类型 TextStyle,文本样式
this.text, // 可选,类型 String,要显示的文字
this.children, // 可选,类型 List<TextSpan>,子TextSpan
this.recognizer, // 可选,类型 GestureRecognizer,一个手势识别器,它将接收到达此文本范围的事件
});
...
}
- RichText 其余参数:
class RichText extends LeafRenderObjectWidget {
const RichText({
Key key, // 可选,类型 Key,Widget 的标识
@required this.text, // 必选,类型 TextSpan,文字片段
this.textAlign = TextAlign.start, // 可选,类型 TextAlign,文本的对齐方式
this.textDirection, // 可选,类型 TextDirection,文字方向
this.softWrap = true, // 可选,类型 bool,是否支持换行
this.overflow = TextOverflow.clip, // 可选,类型 TextOverflow,文本的截断方式
this.textScaleFactor = 1.0, // 可选,类型 double,字体大小的缩放因子
this.maxLines, // 可选,类型 int,显示的最大行数
this.locale, // 可选,类型 Locale,用于选择用户语言和格式设置首选项的标识符
this.strutStyle, // 可选,类型 StrutStyle,设置每行的最小行高
}) : assert(text != null),
...
}
2. 图片和Icon--Image 和 Icon
Image
- 作用:显示图片的 Widget。
- 使用:
(1)Image.asset 的使用
第一步:将本地图片资源添加到Flutter APP
① 在 Flutter 工程的根目录下创建一个 images 目录,然后将一张图片拷贝到该目录;
② 打开 pubspec.xml,在 flutter 中添加图片的配置信息:
方式一,一张一张添加:
flutter:
uses-material-design: true
assets:
- images/flutter.png
方式二,可以把整个目录配置上,就不用一张张图片添加了:
flutter:
uses-material-design: true
assets:
- images/
③ 加载图片:
Image.asset("images/flutter.png"),//显示本地资源图片
(2)Image.network 的使用
Image.network(imageUrl),//显示网络图片
(3)Image.file 的使用
Image.file(file),// 显示文件图片
(4)Image.memory 的使用
Image.memory(bytes), // 显示内存图片
Icon
作用:将图标做成字体文件,然后通过指定不同的字符而显示不同的图片。
和 Image 相比的优势:
① 体积小:可减少安装包大小。
② 矢量的:iconfont 都是矢量图标,放大不会影响其清晰度。
③ 可以应用文本样式:改变字体图标的颜色、大小对齐等。
④ 可以通过 TextSpan 和文本混用使用:
Icon(
Icons.android,
size: 50.0,
color: Colors.green,
)
3. 输入框和表单--TextField 和 Form
TextField
- 作用:文本输入框。
- 使用:
TextField();
- 获取 TextField 的内容
(1)onChanged
TextField的内容发生变化时,就会调用它的 onChanged 回调,我们可以在 onChanged 中获取它的内容。
TextField(
onChanged: (String data) {
//实时获取
print(data);
},
)
(2)TextEditingController
TextEditingController 是 TextField 的控制类,可以控制 TextField 的编辑,是 TextField 的controller 属性,我们可以为 TextField 赋值自己创建的 TextEditingController 对象来控制 TextField。
class TextFieldWidget extends StatelessWidget {
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return
...
TextField(
controller: _controller,
),
...
);
}
}
然后使用 _controller.text 来访问 TextField 里的内容。
Form
- 作用:是用来对输入的信息进行校验的。
- 使用:From 是将多个表单元素组合起来的一个容器,可以将多个表单元素合并起来一起校验。
表单元素的 Widget 是 FormField 及其子类,最常用的是以下两个:
(1)DropdownButtonFormField
(2)TextFormField
使用方法:
第一步:创建From,并为其添加 GlobalKey。
import 'package:flutter/material.dart';
void main() => runApp(FormWidget());
class FormWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return FormWidgetState();
}
}
class FormWidgetState extends State<FormWidget> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
theme: ThemeData(
primaryColor: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text("Flutter UI基础Widget -- Form")),
body: Form(
key: _formKey, // 创建From,并为其添加 GlobalKey
child: ...
)),
);
}
}
第二步:在 From 里添加表单元素,并给表单元素添加校验逻辑。
Form(
key: _formKey,
child: Column(
children: <Widget>[
DropdownButtonFormField<String>(
value: _userGender,
items: ['男', '女']
.map((label) => DropdownMenuItem(
child: Text(label),
value: label,
))
.toList(),
onChanged: (value){
setState(() {
_userGender = value;
});
},
onSaved: (value){
_userGender = value;
},
),
TextFormField(
decoration: InputDecoration(hintText: '用户名'),
validator: (value) { // 校验
if (value?.length <= 5) {
return '用户名必须大于 5 个字符';
}
},
onSaved: (value) {
_userName = value;
},
),
TextFormField(
decoration: InputDecoration(hintText: '密码'),
obscureText: true,
validator: (value) {
if (value?.length <= 8) {// 校验
return '密码必须大于 8 个字符';
}
},
onSaved: (value) {
_userPassword = value;
},
)
],
),
)),
validator
表单元素的验证逻辑是 validator 函数,当表单元素的 value 值,当校验不符合时,就返回一个 String ,这个 String 是错误提示,如果校验成功,就什么也不做。
obscureText
obscureText 设为 Ture,会隐藏当前输入的文字,用 * 代理。
第三步:添加一个按钮去提交并验证表单,提交并验证表单需要用到 Form 的 FormState 方法,Form 是 StatefulWidget,FormState 是 Form 的状态。
Form(
child: Column(
...
RaisedButton(
child: Text('注册'),
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
print(_userGender);
print(_userName);
print(_userPassword);
}
},
)
)),
FormState 为 Form 的 State 类,可以通过 Form.of() 或 GlobalKey 获得。我们可以通过它来对 Form 的子孙 FormField 进行统一操作。常用的三个方法:
① FormState.validate():调用此方法后,会调用 Form 子孙FormField 的 validate 回调,如果有一个校验失败,则返回 false,所有校验失败项都会返回用户返回的错误提示。
② FormState.save():调用此方法后,会调用 Form 子孙FormField 的 save 回调,用于保存表单内容
③ FormState.reset():调用此方法后,会将 子孙FormField 的内容清空。
- Form 的构造函数及参数说明
class Form extends StatefulWidget {
const Form({
Key key, // 可选,类型 Key,Widget的表示
@required this.child, // 必选,类型 Widget,Form 的子 Widget
this.autovalidate = false, // 可选,类型 bool,是否自动验证,默认为 false。当设置 true时,每次输入有变动都会验证;当设置 false 时,只有调用 FormFieldState.validate 才会验证
this.onWillPop, // 可选,类型 WillPopCallback,决定 Form 所在的路由是否可以直接返回,这个回调回返回一个 Future 对象,如果 Future 的最终结果是 false,则当前路由不会返回;如果为 true,则会返回到上一个路由。此属性通常用于拦截返回按钮。
this.onChanged, // 可选,类型 VoidCallback,Form 的任意一个 子 FormField 内容发生变化时会触发此回调。
}) : assert(child != null),
super(key: key);
...
}
总结
本文我们主要介绍了文本框、图片、输入框和表单等基础的 Widget。