Flutter组件基础

Flutter 组件基础

当组件的状态发生改变时,组件会重构自身的描述,并且Flutter框架会对比之前的描述,以确定地层渲染树从当前状态转换到下一个状态所需要的最小更改,最后再执行界面的刷新。

Flutter中真正代表屏幕现实元素的类是Element。Widget只是描述Element的配置数据而已,并且一个Widget可以对应多个Element。如下图所示;

StatelessWidget

表示没有状态的组件。如果想要创建一个无状态的组件,只需要继承 StatelessWidget 根组件,并且重写 build() 方法即可。

由于没有状态,因此StatelessWidget只在初识话阶段构建Widget时才会执行一次渲染,因此它无法基于任何时间或用户操作重绘试图。

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }
}

在该继承和重写的方法中,出现了一个build方法,有一个参数为context。context是当前Widget在Widget树中执行相关操作的一个句柄。可以使用它向上遍历Widget树以及按照Widget类型查找父级Widget。

StatefulWidget

表示有状态的Widget。通过与State对象进行关联来管理组件状态树,内部成员变量不需要使用final修饰符,当需要更新内部变量时,直接使用 setState() 即可。如果Flutter监听到状态树发生变化,那么会触发视图重绘。

如果需要创建一个有状态的组件,需要继承 StatefulWidget ,并且重写 build()

class MyApp extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    throw UnimplementedError();
  }
}
class MyAppState extends State<MyApp>{
  void method(){
    setState(() {
      //进行状态的变更
    });
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }
}

对比于StatelessWidget而言,StatefulWidget多了一个状态。当内部东西需要变更时,通常是调用setState()方法,从而让内部的状态发生改变,从而让Flutter进行重绘。在StatefulWidget中新引入了一个 State<*> 这个是状态改变类。

MaterialApp

作为提供入口的Widget

序号 名称 作用
1 title String类型,Android设备中APP上方显示的标题,在IOS中不起作用。
2 home Widget类型,默认启动后的第一个Flutter。
3 routes Map< String, WidgetBuilder >类型,顶级路由表。
4 theme 定义应用主题
5 theme.primarySwatch 应用的主题色
6 theme.primaryColor 单独设置导航栏的背景颜色

AppBar

顶部导航栏组件,可以用来控制路由、标题和溢出下拉菜单。

序号 名称 解释
1 leading 标题左边的图案按钮,默认是返回箭头的形式
2 title 导航栏标题
3 actions 右边的动作区域中可以放置多个组件,可以是图标或者文字
4 flexibleSpace 位于标题下面的空白空间
5 bottom 位于导航栏地步的自定义组件
6 elevation 控制下方阴影栏的坐标
7 backgroundColor 导航栏的颜色
8 brightness 导航栏材质的亮度
9 textTheme 文本主题设置
10 primary 导航栏是否显示在任务栏顶部
11 centerTitle 标题是否居中现实
12 titleSpacing 标题的间距
13 toolbarOpacity 导航栏透明度,从1到0,透明度从完全不透明到完全透明

AppBar如下图所示

Scaffold

具有Material Design布局风格的Widget,被设计为MaterialApp的顶级容器组件,可以自动填充可用的屏幕空间,占据整个窗口或者设备屏幕。

编号 名称 说明
1 appBar 用于设置顶部的状态栏,如果不设置,那么不显示
2 body Widget类型,现实Scaffold内容的主要容器
3 bottomNavigationBar 设置Scaffold的底部导航栏,items的数量 > 2
4 drawer 设置抽屉效果
5 floatingActionButton 设置右下角的安宁

对于Scaffold中,有一个示例代码如下:

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('首页'),
        ),
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          currentIndex: 1,
          items: const [
            BottomNavigationBarItem(
                icon: Icon(Icons.account_balance),
                title: Text('银行')
            ),
            BottomNavigationBarItem(
                icon: Icon(Icons.contacts),
                title: Text('联系人')
            ),
            BottomNavigationBarItem(
                icon: Icon(Icons.library_music),
                title: Text('音乐')
            )
          ],
        ),
        body: const Center(
          child: Text('联系人页面'),
        ),
      ),
    );
  }
}

经过编译,现实的结果如下:

文本组件

文本组件是Text组件,组件的基本属性如下表

编号 属性名称 类型 说明
1 data String 显示文本的内容
2 style TextStyle 文本的样式
3 strutStyle StrutStyle 每行的最小行高
4 textAlign TextAlign 文本的对齐方式
5 textDirection textDirection 文字方向
6 locale Locale 选择用户语言和格式设置的标识符
7 softWrap bool 是否支持换行
8 overflow TextOverflow 文本的截断方式
9 textScaleFactor double 文本相对于默认字体大小的缩放因子
10 maxLines int 文本显示的最大行数
11 semanticsLabel String 给文本添加一个语义标签

按钮组件

Material组件库中有多个按钮组件

  • RaisedButton
  • FlatButton
  • OutlineButton
  • IconButton

按钮的样例代码如下

import 'package:flutter/material.dart';

void main() => runApp(ButtonWidget());

class ButtonWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Button 组件'),),
        body: Center(
          child: Column(
            children: <Widget>[
              FlatButton(onPressed: () => print('FlatButton'), child: Text('Flat'),),
              RaisedButton(onPressed: ()=>print('RaisedButton'),child: Text("RaisedButton"),),
              FloatingActionButton(onPressed: ()=>print('FloatingActionButton'),child: const Text('FloatingActionButton'),),
              OutlineButton(onPressed: ()=>print('OutlineButton') ,child: const Text("OutlineButton"),),
              IconButton(onPressed: ()=>print("IconButton"), icon: const Icon(Icons.thumb_up))
            ],
          ),
        ),
      ),
    );
  }
}

在代码中,除了FloatingActionButton和IconButton没有被废弃以外,其他均被废弃,不推荐使用。

编号 属性名称 类型 说明
1 textColor Color 按钮的文字颜色
2 disabledTextColor Color 按钮禁用时的文字颜色
3 color Color 按钮的背景颜色
4 highlightColor Color 按钮按下时的背景颜色
5 splashColor Color 单击时产生的水波动画中的水波颜色
6 colorBrightness Brightness 按钮的主题
7 padding EdgeInsetsGeometry 按钮填充距离
8 shape ShapeBorder 按钮的外形
9 child Widget 按钮的文字内容
10 onPressed VoidCallback 按钮点击回调

图片组件

图片组件是用来加载和显示图片的组件。可以使用不同的方式进行加载不同形式的图片。

  • Image 通过ImageProvider来加载图片
  • Image.asset 用来加载本地的图片
  • Image.file 用来加载本地 .file 文件类型的图片
  • Image.network 用来加载网络图片
  • Image.memory 用来加载内存缓存图片
编号 属性名 类型 说明
1 scale double 图片显示的比例
2 semanticsLabel String 给Image加上一个语义标签
3 width double 图片的宽,如果为null,会以默认的形式显示
4 height double 图片的高,如果为null,会以默认的形式显示
5 color Color 图片的混合颜色
6 fit BoxFit 图片的填充模式
alignment Alignment 图片的对齐方式
repeat ImageRepeat 当图片本身小雨显示空间时,指定图片的重复规则
centerSlice Rect 在矩形范围内的图片会被当成.9格式的图片
matchTextDirection Bool 图片的绘制方向,true表示从左往右,false表示从右往左
gaplessPlayback Bool 当图像提供者发生更改时,是否保留原图像
filterQuality FilterQuality 图片的过滤质量

fit填充模式

  • BoxFit.fill 全图显示,不够的部分拉伸
  • BoxFit.contain 全图显示,超过部分被裁减
  • BoxFit.cover 默认显示规则
  • BoxFit.fitWidth 宽度上充满空间,高度按比例缩放,超出部分被裁剪
  • BoxFit.fitHeight 高度充满空间,宽度按比例,超出部分裁剪
  • BoxFit.scaleDown 与contain效果差不多,但是会缩小图像以确保图像位于显示空间内
  • BoxFit.none 没有填充策略,按原大小显示

Image组件图片是有缓存的,默认最大缓存数量是1000,最大空间为100MB。

图标组件

Icon组件是图标组件,也可以使用IconButton。常用组件如下

  • IconButton 可交互的Icon组件
  • Icons 自带的Icon组件集合
  • IconTheme Icon组件主题
  • ImageIcon 通过AssetImages或者图片显示Icon组件

Icon的基本的属性如下

序号 属性名称 类型 说明
1 size double 图标的大小
2 color Color 图标的颜色
3 semanticsLabel String 给图标添加一个语义标签
4 textDirection TextDirection 图标的绘制方向

输入框组件

输入框组件TextField是一个文本输入框组件。常见的属性如下:

序号 属性名称 说明
1 controller 输入框控制器,可以获取和设置输入框的内容以及舰艇文本内容的改变,可自动创建
2 focusNode 控制TextField组件是否获取输入焦点,用户和键盘交互的一种常见方式
3 decoration 用于控制TextField组件的外观显示
4 textAlign 输入框内文本在水平方向的对齐方式
5 textDirection 输入框内文本的方向
6 keyboardType 用于设置默认的键盘输入类型
textInputAction 回车键为动作按钮图标
8 style 输入框的样式
9 autofocus 是否自动获取焦点,默认false
10 obscureText 是否隐藏正在编辑的文本内容
11 maxLines 输入框文本的最大行数
12 maxLength 输入框中允许的最大字符数,使用此属性会在右下角显示已输入的字符数
13 onChange 输入框内容改变时的回调函数
14 onEditingComplete 输入框输入完成时触发
15 onSubmitted 输入框输入完成时触发,返回输入内容
16 inputFormatters 指定输入格式
17 enabled 是否禁用输入框
18 enableInteractiveSelection 是否启用交互式选择,为true时表示长选文字,并且弹出cut、copy、paste菜单
19 keyboardAppearance 设置键盘的亮度模式,IOS专用
20 onTap TextField组件的点击事件
21 buildCounter 自定义InputDecorator.counter小部件的回调方式

表单组件

Form是一个包含表单元素的表单组件,可以用来对输入的信息进行校验。表单的一些属性如下

编号 属性名称 类型 说明
1 child Widget 表单的子组件
2 autovalidate bool 是否自动验证表单内容,默认false
3 onWillPop WillPopCallback 表单所在的路由是否可以直接返回
4 onChanged VoidCallback 表单子元素发生变化时触发的回调
import 'package:flutter/material.dart';

void main(List<String> args) {
  runApp(FormWidget());
}

class FormWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return FormWidgetState();
  }
}

class FormWidgetState extends State<FormWidget> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  String? _userName;
  String? _userPassword;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "flutter demo",
      theme: ThemeData(
        primaryColor: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("Form组件"),
        ),
        body: Form(
          key: _formKey,
          child: Column(
            children: [
              TextFormField(
                decoration: const InputDecoration(
                    hintText: "用户名",
                    icon: Icon(Icons.person)
                ),
                validator: (value) {
                  if (value?.length != null && value!.length <= 5) {
                    return "用户名需要大于5个字符";
                  }
                },
              ),
              TextFormField(
                decoration: const InputDecoration(
                    hintText: "密码",
                    icon: Icon(Icons.lock)
                ),
                obscureText: true,
                validator: (value) {
                  if (value?.length != null && value!.length <= 8) {
                    return "密码必须大于8字符";
                  }
                },
              ),
              RaisedButton(
                onPressed: () {
                  if(_formKey.currentState?.validate()==true){
                    _formKey.currentState?.save();
                  }
                },
                padding: EdgeInsets.all(15.0),
                child: Text("login"),
                color: Theme
                    .of(context)
                    .primaryColor,
                textColor: Colors.white,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

根据上面的代码进行编译运行后,能得到两个简单的输入框以及一个按钮,当用户名或者密码不符合预期时,便会提示错误的信息。

容器组件

Container是Flutter提供的容器组件,可以包含一个子组件,自身具备alignment、margin、padding等基础属性。其包括的属性如下:

序号 属性名称 类型 说明
1 key Key Widget的标识,用于查找更新
2 alignment AlignmentGeometry 容器内子组件的对齐方式
3 padding EdgeInsetsGeometry 容器的内边距
4 color Color 容器的背景颜色
5 decoration Decoration 容器的背景装饰
6 foregroundDecoration Decoration 容器的前景装饰
7 width double 容器的宽度
8 height double 容器的高度
9 constraints BoxConstraints 容器的约束条件
10 margin EdgeInsetsGeometry 容器的外边距
11 transform Matrix4 容器的变化矩阵
12 child Widget 容器里面的子组件

padding包含容器内部的边距,margin是外部的边距。点击padding中的区域会有事件响应,而margin的区域则不会。

盒约束模型

指组件可以按照指定限制条件来决定如何布局自身位置。常见的组件包括

  • ConstrainedBox
  • SizedBox
  • UnconstrainedBox

ConstrainedBox

常见的盒约束组件,用来对子组件添加额外的约束。

ConstrainedBox{
	Key key,
	@required this.constraints,
	Widget child
}

SizedBox

用于给子元素指定固定的宽和高

SizedBox{
	double width,
	double height,
	Widget child
}

SizedBox是ConstrainedBox的子类。

UnconstrainedBox

不会对子组件产生任何限制,允许子组件按照自己本身的大小进行绘制,比较少用到。


参考书籍 《Flutter跨平台开发入门与实战》

posted @ 2021-11-04 11:21  野生的Lemon柠檬  阅读(159)  评论(0编辑  收藏  举报

呱呱呱呱呱🐸