美文网首页
Flutter基础Widget--文本框、图片、输入框和表单

Flutter基础Widget--文本框、图片、输入框和表单

作者: 南小夕 | 来源:发表于2019-07-03 16:14 被阅读0次

    前言

    从本文我们就开始介绍具体的 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。

    相关文章

      网友评论

          本文标题:Flutter基础Widget--文本框、图片、输入框和表单

          本文链接:https://www.haomeiwen.com/subject/bdazqctx.html