在 Flutter 开发中最实用的 Dart 语法知识 的文章中,介绍了 Dart 语法,本篇文章就来说一说 Flutter 开发中常见的组件的用法。



一、Widget(组件)概述



在 Flutter 开发中,记住一句话,一切皆组件。



Flutter 的组件很多,要完全记住是不可能的,我的方法就是记住常见的,然而对于组件的属性,这个不需要记住,根据实际开发需求,需要什么属性,直接点开源码,去查看一下这个组件是否有需要的属性即可。



1.1 概念

Widget 是 Flutter 应用用户界面的基本构建单元,每个 Widget 都最终与用户界面紧密相关。整个页面都是靠 Widget 展示的。一个按钮,一个菜单,一个字体,一个配色方案,一个布局等等都可以看做是 Widget。



1.2 分类

Widget 的分类,主要使用的是两类:

  • StatelessWidget: 内部没有保存状态,UI 界面构建后不会发生改变。
  • StatefulWidget: 内部保存状态,调用 setState() 方法,变更 UI。


1.3 生命周期



flutter android 小组件 flutter的组件_flutter android 小组件

图中有个概念是 Widget 树:

flutter android 小组件 flutter的组件_Stack_02

  • Widget 是为 Element 描述需要的配置,负责创建 Element,决定 Element 是否更新。
  • Element 表示 Widget 配置树的特定位置的一个实例,同时持有 Widget 和 RenderObject,负责管理 Widget 配置和 RenderObject 渲染。
  • RanderObject 表示渲染树的一个对象,负责真正的渲染工作,比如测量大小,绘制位置,都是有 RenderObject 完成。



二、MaterialApp

创建的第一个工程就是带有 MaterialApp Widget 组件的。Material 应用以 MaterialApp Widget 开始,主要封装了应用程序实现 Material Design 需要的一些配置。

flutter android 小组件 flutter的组件_Text_03

从构造方法中,可以看出,这是一个根 Widget,接下来是 Scaffold 组件,翻译过来就是脚手架,这个组件里面配置的一般就是导航栏,页面中间部分,给张图大概说明一下:

flutter android 小组件 flutter的组件_sed_04




三、文本相关组件

3.1 Text

文本组件,对于文本,最需要关心的一般就是文本内容和文本样式。其余属性,按需选择

Text(
       'Text 文本组件',//此参数必传
        maxLines: 1,//最大一行
        softWrap: true, //自动换行
        overflow: TextOverflow.ellipsis, //超出内容如何显示:3小点
        
        //样式属性
        style: TextStyle(
            fontSize: 30.0, //大小        
)



3.2 RichText

富文本组件,文本的内容可以分段显示不同的样式。源码中 text 属性必须传入,类型是 InlineSpan 类型的,而 TextSpan 继承 InlineSpan 的。

RichText(
  text: TextSpan(
    text: '富文本',
        style: TextStyle(color: Color(0xffff0000), fontSize: 20.0),
        children: <TextSpan>[
        TextSpan(text: '富文本1', ),
        TextSpan(text: '富文本2', style: TextStyle(color:Color(0xff0000ff)),)
      ],
    ),
 ),



3.3 TextField

文本输入框,一般最关心的是默认 hint 值,文本输入的限制等。

TextField(
           //最普通的样式
           controller: TextEditingController(text: "input phone"),
           //装饰
           decoration: InputDecoration(
             //hint 文字
             hintText: "please input phone",
             //外边框
             border: OutlineInputBorder(),
           ),
           inputFormatters: [
             //过滤 白名单:数字 11位
             WhitelistingTextInputFormatter.digitsOnly,
             LengthLimitingTextInputFormatter(11)
           ],
           //密码形式
           obscureText: true,
)




四、图片组件

顾名思义,展示图片的组件,这边就简单介绍几种图片展示方式

4.1 显示网络图片
Image.network(
            'https://www.baidu.com/img/bd_logo1.png?where=super',
                height: 100.0,
                width: 100.0,
 ),

从源码中看出 src 必传,width,height 设置图片宽高。



4.2 显示 assets 目录下图片
//例如:
// 1. 项目根目录下创建 assets 文件夹,此文件夹下创建 images 文件夹,将设计给的图片放入其中
// 2. 在 pubspec.yaml 文件中写入

flutter:
  assets:
    - assets/images/tzd.jpg
    

// 3. 加载图片
Image.asset(
    'assets/images/tzd.jpg',
    height: 200.0,
    width: 200.0,
)



4.3 Icon 组件展示图片

系统内置了很多 Icon 的图片,供开发者使用。

Icon(
              Icons.folder,
              color: Colors.red,
              size: 50,
)



4.4 圆形图片

正常都会有展示圆形图片的需求,使用组件 ClipOval

ClipOval(
     child: Image(
        image: NetworkImage( "https://img.aigaojixtxz.com/d/file/images/20191113/15690311636958128.jpg"),
        width: 50,
        height: 50,
  )

对于圆形图片,再介绍一种方式供选择:

Container(
    width: 50,
    height: 50,
    decoration: BoxDecoration(
        image: DecorationImage(
              image: NetworkImage( "https://img.aigaojixtxz.com/d/file/images/20191113/15690311636958128.jpg")),
              shape: BoxShape.circle,
     ),
  )

这边的 Container 是一个容器组件,类似于 HTML 中的 div。对于常见的功能,从相册中选择图片,推荐使用 image_picker 这个插件。




五、按钮组件

对于按钮,就简单介绍两个最常见的 IconButtonRasiedButton

IconButton(icon: Icon(Icons.error), onPressed: () {}),
  RaisedButton(
                onPressed: () {},
                child: Text('RaisedButton'),
              )

IconButton 是带图标的按钮,其中的 onPressed() 是点击事件,RasiedButton 是自带水波纹的按钮。




六、对话框组件

比较简单一点的是 SimpleDialog 组件:

SimpleDialog(
              title: Text('对话框标题'),
              children: <Widget>[
                SimpleDialogOption(
                  child: Text('选项1'),
                  onPressed: () {
                    print('选项1');
                  },
                ),
                SimpleDialogOption(
                  child: Text('选项2'),
                  onPressed: () {
                    print('选项2');
                  },
                )
              ],
            )

然而开发中一般使用的 AlertDialog

AlertDialog(
                        title: Text('提示'),
                        content: SingleChildScrollView(
                          child: ListBody(
                            children: <Widget>[
                              Text('是否删除?'),
                              Text('删除后不可恢复!'),
                            ],
                          ),
                        ),
                        actions: <Widget>[
                          FlatButton(
                            child: Text('确定'),
                            onPressed: () {
                              Navigator.of(context).pop();
                            },
                          ),
                          FlatButton(
                            child: Text('取消'),
                            onPressed: () {
                              Navigator.of(context).pop();
                            },
                          ),
    );




七、布局组件

关于布局组件,主要使用的有三种:线性布局弹性布局层叠布局

7.1 线性布局

线性布局:指沿水平或垂直方向排布子组件。 Flutter 中通过 RowColumn 来实现线性布局。

对于线性布局来说,有个比较重要的概念:主轴和交叉轴。来张图展示一下:

flutter android 小组件 flutter的组件_Text_05

对上面的图解释一下:

  • 如果你的布局方向是水平方向(Row),那么你的主轴(Main Axis)也就是水平方向,交叉轴(Cross Axis)也就是在竖直方向。
  • 如果你的布局方向是竖直方向(Column),那么你的主轴(Main Axis)也就是竖直方向,交叉轴(Cross Axis)也就是在水平方向。

千言万语不如一张图

flutter android 小组件 flutter的组件_sed_06



7.2 弹性布局
  • 允许子组件按照一定比例来分配父容器空间。Flutter 中的弹性布局主要通过 FlexExpanded 来配合实现。
class SimpleFlex extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Simple Flex'),
      ),
      body: Flex(
        //方向:水平方向布局
        direction: Axis.horizontal,
        children: <Widget>[
          Expanded(
            flex: 1,
            child: Container(
              color: Colors.red,
              height: 50,
            ),
          ),
          Expanded(
            flex: 1,
            child: Container(
              color: Colors.green,
              height: 50,
            ),
          ),
          Expanded(
            flex: 2,
            child: Container(
              color: Colors.yellow,
              height: 50,
            ),
          ),
        ],
      ),
    );
  }
}



7.3 层叠布局
  • 层叠布局能够将子控件层叠排列。Flutter 中 Stack 允许子组件堆叠,而 Positioned 用于根据 Stack 的四个角来确定子组件的位置。
Stack:

flutter android 小组件 flutter的组件_sed_07

Positioned:

flutter android 小组件 flutter的组件_Text_08

class SimpleStack extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Simple Stack'),
      ),
      body: Stack(
        //此参数决定如何去对齐没有定位或部分定位的子组件
        alignment: AlignmentDirectional.topStart,
        //fit:此参数用于确定没有定位的子组件如何去适应Stack的大小
        //overflow :此属性决定如何显示超出Stack显示空间的子组件
        children: <Widget>[
          Container(
            color: Colors.red,
          ),
          //单个组件定位
          Positioned(
            left: 100,
            child: Container(
              width: 150,
              height: 150,
              color: Colors.green,
            ),
          ),
          Container(
            width: 100,
            height: 100,
            color: Colors.yellow,
          )
        ],
      ),
    );
  }
}




八、卡片组件

这类的组件类似于 Android 中的 CardView 控件。

Widget buildCard() {
    return Container(
      child: Card(
        elevation: 5,//阴影
        //图片显示圆角
        clipBehavior: Clip.antiAlias,
        shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(14.0))),  //设置圆角
        child: Column(
          children: <Widget>[
            Container(
              child: Image.asset(
                'assets/images/tzd.jpg',
                width: double.infinity,
                height: 150.0,
                fit: BoxFit.cover,
              ),
            ),
            Row(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.all(15.0),
                  child: Container(
                    child: Icon(Icons.home),
                  ),
                ),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        '棒棒的',
                        style: TextStyle(fontSize: 22.0),
                      ),
                      Text(
                        '500',
                        style: TextStyle(fontSize: 14.0),
                      ),
                    ],
                  ),
                ),
                Container(
                  child: Column(
                    children: <Widget>[
                      Icon(
                        Icons.favorite,
                        color: Color(0xffff0000),
                      ),
                      Text('66'),
                    ],
                  ),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }




最后

本篇文章介绍了 Flutter 开发中的最常用的基础组件,希望各位有所收获。 本人水平有限,如有错误,请在下方评论中指出。