Flutter学习笔记

1,120 阅读13分钟

1、flutter的开始

1、认识文件夹

文件夹名称作用
androidandroid平台相关代码
iosios平台相关代码
libflutter相关代码,主要编写的代码放入该文件夹
test用于存放测试代码
pubspec.yaml配置文件,项目相关信息,一般存放第三方库的依赖

2、入口文件/入口方法

入口文件:flutter项目的lib目录里面都有一个main.dart这个文件就是flutter的入口文件

入口方法:main.dart文件中的

void main() {
  runApp(MyApp());
}
//也可也简写一下
void main()=>runApp(MyApp());

其中main方法是dart的入口方法。runApp方法是flutter的入口方法。MyApp是自定义的一个组件。

2、flutter基本

从最根本的开始哦。

1、Helloworld

import 'package:flutter/material.dart';

void main() {
  runApp( Center(
    child: Text(
      'CDX',
      textDirection: TextDirection.ltr,
    )
  ));
}

实现效果:

2、自定义组件

在flutter中自定义组件其实就是一个类,这个类需要继承StatelessWidget/StatefulWidget。

StatelessWidget:是无状态组件,状态不可变的widget。

StatefulWidget:是有状态组件,持有的状态可能在widget生命周期改变。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

//自定义组件
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Text(
      'CDX111',
      textDirection: TextDirection.ltr,
      style: TextStyle(
        fontSize: 40.0,
        color: Colors.yellow,
      ),
    ));
  }
}

实现效果:

3、组件:MaterialApp/Scaffold

1、MaterialApp组件是一个方便的Widget,它封装了应用程序实现Material Design所需要的一些Widget。一般作为顶层widget使用。

2、Scaffold组件是Material Design布局结构的基本实现。此类提供了用于显示drawer、snackbar和底部sheet的API。

代码块:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('flutter cdx'),
        ),
        body: HomeContent(),
      ),
    );
  }
}
class HomeContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Text(
      'CDX111',
      textDirection: TextDirection.ltr,
      style: TextStyle(
        fontSize: 40.0,
        color: Colors.yellow,
      ),
    ));
  } 
}

完整代码:

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('flutter cdx'),
        ),
        body: HomeContent(),
      ),
    );
  }
}

class HomeContent extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Text(
      'CDX111',
      textDirection: TextDirection.ltr,
      style: TextStyle(
        fontSize: 40.0,
        color: Colors.yellow,
      ),
    ));
  } 
}

实现效果:

4、组件:Container/Text 详解

1、Container组件

该组件可以被用来看作是我们之前的一个div,其实他就是一个对象,我们来看一下他的构造函数吧。

Container组件属性描述

属性名类型说明
keyKeyContainer 一标识符,用于查找更新
alignmentAlignmentGeometry控制child 的对齐方式,如果Container或者 Container 父节点尺寸大于child 的尺寸,这个属性设置会起作用,有很多种对齐方式
paddingEdgelnsetsGeometryDecoration内部的空白区域,如果有child的话,child 位于padding 内部
colorColor用来设置 Contain 背景色,如果foregroundDecoration设置的话,可能会遮盖color效果
decorationDecoration绘制在child后面的装饰,设置了 Decoration 话,就不能设置color 属性,否则会报错,此时应该在 Decoration中进行颜色的设置
foregroundDecorationDecoration绘制在child前面的装饰
widthdoubleContainer的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局
heightdoubleContainer的高度,设置为double.infinity可以强制在高度上撑满
constraintsBoxConstraints添加到child上额外的约束条件
marginEdgelnsetsGeometry围绕在Decoration和child之外的空白区域,不属于内容区域
transformMatrix4设置Container的变换矩阵,类型为Matrix4
childWidgetContainer中的内容Widget

2、Text组件

Text组件属性描述

属性名类型默认值说明
dataString数据为要显示的文本
maxLinesint0文本显示的最大行数
styleTextStylenull文本样式,可定义文本的字体大小、颜色、粗细等
textAlignTextAlignTextAlign.center文本水平方向对齐方式,取值有center、end、justify、left、right、start、values
textDirectionTextDirectionTextDirection.ltr文本书写方向。ltr从左到右,rtl从右到左
textScaleFactordouble1.0字体缩放系数
textSpanTextSpannull文本块

3、示例

//自定义组件
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('flutter cdx'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        child: Text(
          'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
          textAlign: TextAlign.center,
          overflow: TextOverflow.fade,
          style: TextStyle(
              fontSize: 16.0,
              color: Colors.red,
              fontWeight: FontWeight.w700,
              fontStyle: FontStyle.italic,
              decoration: TextDecoration.lineThrough,
              decorationColor: Colors.white,
              decorationStyle: TextDecorationStyle.dashed),
        ),
        height: 300.0,
        width: 300.0,
        decoration: BoxDecoration(
            color: Colors.green,
            border: Border.all(color: Colors.blue, width: 2.0),
            borderRadius: BorderRadius.all(Radius.circular(150))
            ),
            transform: Matrix4.rotationZ(0.3),
      ),
    );
  }
}

效果:

5、图片组件

基础代码块:(本节代码基础部分,其余效果展示代码均在HomeContent中)

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('flutter cdx'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

1、介绍

1、new Image:从ImageProvideer 获取图片

2、new Image.asset:加载资源图片

3、new Image.file:加载本地图片文件

4、new Image.netWork:加载网络图片

5、new Image.memory:加载Uint8List资源图片。

Image组件属性描述

属性名类型说明
imageImageProvider抽象类,需要自己实现获取图片数据的操作
width/hei ghtdoubleImage显示区域的宽度和高度设置
fitBoxfit图片填充模式
colorColor图片颜色
colorBlendModeBlendMode在对图片进行手动处理的时候,可能会用到图片混合如改变图片的颜色。此属性可以对颜色进行混合处理。
alignmentAlignment控制图片的摆放位置
repeatImageRepeat设置图片重复模式
centerSliceRect当图片需要被拉伸时使用
matchTextDirectionbooI该属性与Directionlity配合使用
gaplessPlaybackbool当ImageProvide发生变化后,重新加载图片的过程中,原图片的展示是否保留

BoxFit取值描述

取值描述
Boxfit.fill全图显示,显示可能拉伸,充满
Boxfit.contain全图显示,显示原比例,不需充满
Boxfit. cover显示可能拉伸,可能裁剪,充满
BoxFit.fitWidth显示可能拉伸,可能裁剪,宽度充满
BoxFit.fitHeight显示可能拉伸,可能裁剪,高度充满
Boxfit.none原始大小
BoxFit.scaleDown效果和BoxFit.contain差不多,但是此属性不允许显示超过源图片大小,即可小不可大

2、远程图片示例

mage.network(src)

简单示例:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        child: Image.network(
          "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
        colorBlendMode: BlendMode.screen,
        fit: BoxFit.cover,),
        width: 300,
        height: 300,
        decoration: BoxDecoration(
          color: Colors.green,
        ),
      ),
    );
  }
}

效果:

3、实现圆角以及圆形图片

1、使用borderRadius和BoxFit.cover实现

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
      width: 300,
      height: 300,
      decoration: BoxDecoration(
        color: Colors.green,
        borderRadius: BorderRadius.circular(150),//*********
        image: DecorationImage(
          image: NetworkImage(      "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
          ),
          fit: BoxFit.cover,//************
        ),
      ),
    ));
  }
}

效果:

2、使用ClipOval实现

1、首先看clipOval处理的效果

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
          child: ClipOval(
            child: Image.network("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",),
          ),
    ));
  }
}

效果:

2、继续变圆

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
          child: ClipOval(
            child: Image.network("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
            height: 300,
            width: 300,
            fit: BoxFit.cover,),
          ),
    ));
  }
}

效果:

2、本地图片

1、相关文件夹的创建与配置文件修改

2、示例

1、代码

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
          child: Image.asset("images/1.jpg"),
    ));
  }
}

2、效果

6、列表组件

基础代码块:(本节代码基础部分,其余效果展示代码均在HomeContent中)

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('flutter cdx'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

1、介绍

列表大致有以下分类

1、水平的列表

2、垂直的列表

3、数据量非常大的列表

4、矩阵式的列表

ListView组件的基本属性

属性名类型默认值说明
scrollDirectionAxisAxis.vertical列表的排列方向,Axis.vertical为垂直方法式默认值,Axis.horizontal为水平方法
paddingEdgelnsetsGeometry列表内部的空白区域,如果有child的话,child位于padding内部
reverseboolfalse组件排列反向
childrenList列表元素,注意List元素全部为Widget

2、垂直列表

代码:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ListTile(
          leading: Image.asset("images/1.jpg"),
          title: Text("xxxxxxxxxxxxxxxxxxxxx"),
          subtitle: Text("ccccccccccccccccccc"),
        ),
        ListTile(
          title: Text("xxxxxxxxxxxxxxxxxxxxx"),
          subtitle: Text("ccccccccccccccccccc"),
          trailing: Icon(Icons.search),
        ),
        ListTile(
          leading: Icon(Icons.padding),
          title: Text("xxxxxxxxxxxxxxxxxxxxx"),
          subtitle: Text("ccccccccccccccccccc"),
        ),
        ListTile(
          leading: Icon(Icons.games),
          title: Text("xxxxxxxxxxxxxxxxxxxxx"),
          subtitle: Text("ccccccccccccccccccc"),
        ),
        ListTile(
          leading: Icon(Icons.ac_unit_sharp),
          title: Text("xxxxxxxxxxxxxxxxxxxxx"),
          subtitle: Text("ccccccccccccccccccc"),
        ),
        ListTile(
          leading: Icon(Icons.tab),
          title: Text("xxxxxxxxxxxxxxxxxxxxx"),
          subtitle: Text("ccccccccccccccccccc"),
        ),
      ],
    );
  }
}

效果:

3、水平列表

代码:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      child:ListView(
      scrollDirection: Axis.horizontal,
      children: <Widget>[
        Container(
          width: 100,
          height: 100,
          color: Colors.green,
        ),
        Container(
          width: 100,
          height: 100,
          color: Colors.blue,
        ),
        Container(
          width: 100,
          height: 100,
          color: Colors.red,
        ),
        Container(
          width: 100,
          height: 100,
          color: Colors.grey,
        ),
        Container(
          width: 100,
          height: 100,
          color: Colors.deepOrange,
        ),
      ],
    )
    );
  }
}

效果:

4、动态列表

代码:

class HomeContent extends StatelessWidget {
  List<Widget> getData() {
    List<Widget> list = new List();
    for (var i = 1; i <= 7; i++) {
      list.add(ListTile(
        title: Text("xxxxxx$i个"),
      ));
    }
    return list;
  }
  @override
  Widget build(BuildContext context) {
    return Container(child: ListView(children: this.getData()));
  }
}

ListView.builder

class HomeContent extends StatelessWidget {
  List list = new List();
  HomeContent() {
    
    for (var i = 1; i <= 7; i++) {
      list.add("xxxxxx$i个");
    }
  }
  @override
  Widget build(BuildContext context) {
    return Container(child: ListView.builder(
      itemCount: this.list.length,
      itemBuilder: (context,index){
        return ListTile(
          title: Text(this.list[index]),
        );
      },
    ));
  }
}

效果:

7、GridView组件

基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)

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('flutter cdx'),
        ),
        body: Demo(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

GridView组件属性及描述

属性名类型默认值说明
scrollDirectionAxisAxis.vertical滚动的方向,有垂直和水平两种,默认为垂直方向
reverseboolfalse默认是从上或者左向下或者向右滚动的,这个属性控制是否反向,默认值为false,即不反向滚动
controllerScrollController控制child滚动时候的位置
primarybool是否是与父节点的PrimaryScrollcontroller所关联的主滚动视图
physicsScrollPhysics滚动的视图如何响应用户的输入
shrinkWrapboolfalse滚动方向的滚动视图内容是否应该由正在查看的内容所决定
paddingEdgeinsetsGeometry四周的空白区域
gridDelegateSliverGridDelegate控制GridView中子节点布局的delegate
cacheExtentdouble缓存区域

1、通过GridView.count实现网格布局

代码:

class Demo extends StatelessWidget {
  List<Widget> getData() {
    List<Widget> list = new List();
    for (var i = 0; i < 20; i++) {
      list.add(Container(
        alignment: Alignment.center,
        child: Text(
          'xxxxx $i xxxx',
          style: TextStyle(color: Colors.white,fontSize: 20),
        ),
        color: Colors.blue,
      ));
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisSpacing: 10.0, //水平子Widget之间的距离
      mainAxisSpacing: 10.0, //垂直widget之间距离
      padding: EdgeInsets.all(10),
      crossAxisCount: 3, //控制一行有多少个Widget
      childAspectRatio: 0.7,//宽度和高度的比例
      children: this.getData(),
    );
  }
}

效果:

2、通过GridView.builder实现网格布局

代码:

class Demo extends StatelessWidget {
  Widget getData(context, index) {
    return Container(
      child: Column(
        children: <Widget>[
          Image.asset("images/1.jpg"),
          SizedBox(height: 12),
          Text(
            "xxxxxxxx",
            textAlign: TextAlign.center,
            style: TextStyle(fontSize: 20),
          )
        ],
      ),
      decoration: BoxDecoration(
        border: Border.all(color: Colors.blue, width: 1),
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      // padding: EdgeInsets.all(10),
      // crossAxisCount: 3, //控制一行有多少个Widget
      // childAspectRatio: 0.7,//宽度和高度的比例
      // children: this.getData(),
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisSpacing: 10.0, //水平子Widget之间的距离
        mainAxisSpacing: 10.0, //垂直widget之间距离
        crossAxisCount: 3, //控制一行有多少个Widget
      ),
      itemCount: 10,
      itemBuilder: this.getData,
    );
  }
}

效果:

8、页面布局 Padding/Row/Column/Expanded

基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)

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('flutter cdx'),
        ),
        body: Demo(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

GridView组件属性及描述

1、Padding组件

在html中常见的布局标签都有padding属性,但是Fliuuter中很多widget是没有padding属性的。这时候我们可以用Padding组件处理容器与子元素之间的间距

属性说明
paddingpadding值,EdgeInsetss设置填充的值
child子组件

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
      crossAxisCount: 3, //控制一行有多少个Widget
      childAspectRatio: 1.7,//宽度和高度的比例
      children: <Widget>[
        Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
        Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
         Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
         Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
         Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
         Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
         Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
         Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
         Padding(
          padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
          child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
        ),
      ],
    );
  }
}

效果:

2、Row水平布局组件

属性介绍:

属性说明
mainAxisAlignment主轴的排序方式
crossAxisAlignment次轴的排序方式
children组件子元素

3、Column垂直布局组件

实现一个图标组件:实现传入图标(颜色和大小动态)

代码:

class IconDemo extends StatelessWidget {
  double size = 32.0;
  Color color = Colors.red;
  IconData icon;
  IconDemo(this.icon, {this.color, this.size});
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 100.0,
      width: 100.0,
      color: this.color,
      child: Center(
        child: Icon(
          Icons.home,
          size: 32,
          color: Colors.white,
        ),
      ),
    );
  }
}

通过上述组件测试Row的排序

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 600.0,
      width: 600.0,
      child:Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      crossAxisAlignment: CrossAxisAlignment.start,
      
      children: <Widget>[
        IconDemo(
          Icons.home,
          color: Colors.green,
        ),
        IconDemo(
          Icons.search,
          color: Colors.red,
        ),
        IconDemo(
          Icons.fit_screen,
          color: Colors.green,
        ),
      ],
    )
    );
  }
}

class IconDemo extends StatelessWidget {
  double size = 32.0;
  Color color = Colors.red;
  IconData icon;
  IconDemo(this.icon, {this.color, this.size});
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 100.0,
      width: 100.0,
      color: this.color,
      child: Center(
        child: Icon(
          Icons.home,
          size: 32,
          color: Colors.white,
        ),
      ),
    );
  }
}

效果:

4、Expanded组件

Flutter中Expanded组件类似Web中的Flex布局

Expanded可以用在Row和Column布局中

属性说明
flex元素占整个父Row/Column的比例
child子元素

代码:(未包含上述IconDemo组件的代码)

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Expanded(
          flex: 1,
          child: IconDemo(
            Icons.home,
            color: Colors.green,
          ),
        ),
        Expanded(
          flex: 2,
          child: IconDemo(
            Icons.search,
            color: Colors.red,
          ),
        ),
      ],
    );
  }
}

效果:

5、相关案例

实现一个类似于下图的布局

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Row(
          children: <Widget>[
            Expanded(
              child: Container(
                height: 200,
                color: Colors.blue,
                child: Text("xxxxxxxxxx"),
              ),
            )
          ],
        ),
        SizedBox(height: 10),
        Row(children: <Widget>[
          Expanded(
              flex: 2,
              child: Container(
                  height: 180,
                  child: Image.asset(
                    "images/1.jpg",
                    fit: BoxFit.cover,
                  ))),
          Expanded(
              flex: 1,
              child: Container(
                  height: 180,
                  child: ListView(children: <Widget>[
                    Container(
                        height: 85,
                        child: Image.asset(
                          "images/1.jpg",
                          fit: BoxFit.cover,
                        )),
                    SizedBox(height: 10),
                    Container(
                        height: 85,
                        child: Image.asset(
                          "images/1.jpg",
                          fit: BoxFit.cover,
                        ))
                  ]))),
        ]),
      ],
    );
  }
}

效果:

9、页面布局 Stack层叠组件/Stack与Aligin/Stack与Positioned

基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)

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('flutter cdx'),
        ),
        body: Demo(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

1、Stack组件

属性说明
alignment配置所有子元素的显示位置
children子组件

stack效果:有点像元素重叠一样,下面展示文字和容器效果

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
          height: 400,
          width: 300,
          color: Colors.red,
        ),
        Text("xxxxxxxxxxx")
      ],
    );
  }
}

效果:

通过alignment属性进行位置移动

还可以是坐标

alignment: Alignment(0,0),

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      // alignment: Alignment.center,
      // alignment: Alignment(0,0),
      alignment: Alignment.center,
      children: <Widget>[
        Container(
          height: 400,
          width: 300,
          color: Colors.red,
        ),
        Text("xxxxxxxxxxx")
      ],
    );
  }
}

效果:

2、align/positiond

上述stack如果里面有两个文本的话,就会导致两个文本出现重叠的现象如下:

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      // alignment: Alignment.center,
      // alignment: Alignment(0,0),
      alignment: Alignment.center,
      children: <Widget>[
        Container(
          height: 400,
          width: 300,
          color: Colors.red,
        ),
        Text("xxxxxxxxxxx"),
        Text("ddddddddddd"),
      ],
    );
  }
}

效果:

使用align

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 400,
        width: 400,
        color: Colors.blue,
        child: Stack(children: <Widget>[
          Align(
            alignment: Alignment.topLeft,
            child:  Icon(Icons.help, size: 40, color: Colors.white),
          ),
          Align(
            alignment: Alignment.center,
            child: Icon(Icons.search, size: 40, color: Colors.white),
          ),
          Align(
            alignment: Alignment.bottomRight,
            child: Icon(Icons.home_filled, size: 40, color: Colors.white),
          ), 
        ]),
      ),
    );
  }
}

效果:

使用positiond
属性说明
top子元素距离顶部的距离
bottom子元素距离底部的距离
left子元素距离左侧的距离
right子元素距离右侧的距离
child子组件

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 400,
        width: 400,
        color: Colors.blue,
        child: Stack(children: <Widget>[
          Positioned(
            left: 10,
            child:  Icon(Icons.help, size: 40, color: Colors.white),
          ),
          Positioned(
            bottom: 0,
            child: Icon(Icons.search, size: 40, color: Colors.white),
          ),
          Positioned(
            right: 0,
            child: Icon(Icons.home_filled, size: 40, color: Colors.white),
          ), 
        ]),
      ),
    );
  }
}

效果:

10、AspectRatio组件/Card组件

基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)

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('flutter cdx'),
        ),
        body: Demo(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

1、AspectRatio

AspectRatio的作用是根据设置调整子元素child的宽高比。

AspectRatio首先会在布局限制条件允许的范围内尽可能的扩展,widget的宽度是由宽度和比率决定的,类似于BoxFit中的contain,按照固定比率去尽量占满区域。

如果在满足所有限制条件过后无法找到一个可行的尺寸,AspectRatio最终将会去优先适应布局限制条件,而忽略所设置的比率

属性说明
aspectRatio宽高比,最终可能不会根据这个值去布局,具体要看综合因素,外层是否允许按照这种比例进行布局,这只是一个参考值
child子组件

代码:(长是高的2倍例子)

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      child: AspectRatio(
        aspectRatio: 2.0/1.0,//外层的200,会是里面的container长200高100
        child: Container(
          color: Colors.red,
        ),
      ),
    );
  }
}

2、Card

Card是卡片组件块,内容可以由大多数类型的Widget构成,Card具有圆角和阴影,这让它看起来有立体感。

属性说明
margin外边距
child子组件
ShapeCard的阴影效果,默认的阴影效果为圆角的长方形边。

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Card(
          margin:EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              ListTile(
                title:Text('chidaoxian'),
                subtitle: Text('前端开发工程师'),
              ),
               ListTile(
                title:Text('电话:12323432141234123'),
               
              ),
               ListTile(
                title:Text('地址:xxxxxx'),
                
              ),
            ],
          ),
        ),
        Card(
          margin:EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              ListTile(
                title:Text('chidaoxian'),
                subtitle: Text('前端开发工程师'),
              ),
               ListTile(
                title:Text('电话:12323432141234123'),
               
              ),
               ListTile(
                title:Text('地址:xxxxxx'),
                
              ),
            ],
          ),
        ),
      ],
    );
  }
}

效果:

11、Wrap组件

基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)

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('flutter cdx'),
        ),
        body: Demo(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

1、介绍

wrap组件可以实现流布局,单行的Wrap跟Column表现几乎一致,单列的Wrap则跟Row表现几乎一致。但Row与Column都是单行单列,Wrap则突破了这个限制,mainAxis上空间不足时,则向crossAxis上去扩展显示。

属性说明
direction主轴的方法,默认水平
alignment主轴的对齐方式
spacing主轴方向上的间距
textDirection文本方向
verticalDirection定义了children摆放顺序,默认是down,见flex相关属性介绍
runAlignmentrun的对齐方式。run可以理解为新的行或者列,如果是水平方向布局的话,run可以理解为新的一行
runSpacingrun的间距

2、wrap实例

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing:10,
      // runSpacing:5,
      children: <Widget>[
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
      MyButton('xxx'),
    ]);
  }
}
class MyButton extends StatelessWidget {
  final String text;
  const MyButton(this.text, {Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text(this.text),
      textColor: Theme.of(context).accentColor,
      onPressed: () {},
    );
  }
}

效果:

12、StatefulWidget有状态组件、页面上绑定数据、改变页面数据

基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)

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('flutter cdx'),
        ),
        body: Demo(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

1、介绍

StatefulWidget是有状态组件,持有的状态可能在Widget生命周期改变。通俗的讲:如果我们想改变页面中的数据的话这个时候就需要用到StatefulWidget。

2、有状态组件/数据绑定

代码:

class Demo extends StatefulWidget {
  Demo({Key key}) : super(key: key);

  @override
  _DemoState createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  int countNum = 0;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        SizedBox(height: 20,),
        Chip(label: Text('${this.countNum}')),
        SizedBox(height: 20,),
        RaisedButton(
          child: Text('按钮'),
          onPressed: (){
            setState(() {
              this.countNum++;
            });
          },
        )
      ],
    );
  }
}

效果:

13、ButtonNavigationBar组件

1、介绍

ButtonNavigationBar 是底部导航条,可以让我们定义底部Tab切换,buttonNavigationBar是Scaffold组件参数。

属性名类型说明
currentlndexint当前索引,用来切换按钮控制
fixedColorColor选中按钮的颜色。如果没有指定值,则用系统主题色
iconSizedouble按钮图标大小
itemsList底部导航调按钮集。每一项是一个BottomNavigationBarItem,有icon图标及title文本属性
onTapValueChanged按下其中某一个按钮回调事件。需要根据返回的索引设置当前索引

2、实例

1、效果:

底部导航切换页面效果:

代码介绍:

代码:

1、main.dart的代码

import 'package:flutter/material.dart';
import 'package:flutter_app01/pages/tabs/Home.dart';
import 'pages/tabs/Tabs.dart';
import 'pages/tabs/ddd.dart';
import 'pages/tabs/Setting.dart';

void main() {
  runApp(MyApp());
}

//自定义组件
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Tabs(),
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
    );
  }
}

class Tabs extends StatefulWidget {
  Tabs({Key key}) : super(key: key);

  @override
  _TabsState createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  int currentIndex = 0;

  List pageList = [
    HomePage(),
    SettingPage(),
    DDDPage(),
  ];
  @override
  Widget build(BuildContext context) {
    return Container(
       child: Scaffold(
        appBar: AppBar(
          title: Text('flutter cdx'),
        ),
        body: this.pageList[this.currentIndex],
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: this.currentIndex,
          onTap: (int index) {
            setState(() {
              this.currentIndex = index;
            });
          },
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: '首页',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.my_library_books),
              label: '我的',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.settings_applications),
              label: '设置',
            ),
          ],
        ),
      ),
    );
  }
}

2、Tabs.dart的代码

import 'package:flutter/material.dart';

class Tabs extends StatefulWidget {
  Tabs({Key key}) : super(key: key);

  @override
  _TabsState createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  int currentIndex = 0;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Scaffold(
        appBar: AppBar(
          title: Text('flutter cdx'),
        ),
        body: Text('xxx'),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: this.currentIndex,
          onTap: (int index) {
            setState(() {
              this.currentIndex = index;
            });
          },
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: '首页',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.my_library_books),
              label: '我的',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.settings_applications),
              label: '设置',
            ),
          ],
        ),
      ),
    );
  }
}

3、Home.dart的代码(Home.dart/Setting.dart代码类似)

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
       child: Text('HomePage'),
    );
  }
}

14、Flutter中的基本路由

flutter中的路由通俗的讲就是页面跳转。在flutter中通过Navigator组件管理路由导航。并提供了管理堆栈的方法。如:Navigator.push 和Navigator.pop

flutter中给我们提供了两种配置路由跳转的方式:1、基本路由 2、命名路由

1、简单路由跳转

代码:

import 'package:flutter/material.dart';
import '../Search.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        RaisedButton(
          child: Text('跳转搜索页面'),
          onPressed: (){
            Navigator.of(context).push(
             MaterialPageRoute(
               builder: (context)=> SearchPage()
             )
            );
          },
        ),
      ],
    );
  }
}

2、跳转传值

代码:

import 'package:flutter/material.dart';

class SearchPage extends StatefulWidget {
  SearchPage({Key key}) : super(key: key);

  @override
  _SearchPageState createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  String title ;
  _SearchPageState({this.title = 'cdx'});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("${this.title}页面"),
      ),
      body: Text("内容区域"),
    );
  }
}


3、返回

代码:

import 'package:flutter/material.dart';

class SearchPage extends StatefulWidget {
  SearchPage({Key key}) : super(key: key);

  @override
  _SearchPageState createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  String title ;
  _SearchPageState({this.title = 'cdx'});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        child: Text('返回'),
        onPressed: (){
          Navigator.of(context).pop();
        },
      ),
      appBar: AppBar(
        title: Text("${this.title}页面"),
      ),
      body: Text("内容区域"),
    );
  }
}

效果:

15、Flutter命名路由

1、不携带参数

main.dart文件配置:**

路由跳转方式:

2、携带参数

Routes.dart文件

import 'package:flutter/material.dart';
import 'package:flutter_app01/pages/tabs/Tabs.dart';
import 'package:flutter_app01/pages/tabs/ddd.dart';
import 'package:flutter_app01/pages/tabs/Setting.dart';
import 'package:flutter_app01/pages/Search.dart';
import 'package:flutter_app01/pages/tabs/Home.dart';

final routes = {
  '/': (context, {arguments}) => Tabs(),
  '/home': (context, {arguments}) => HomePage(),
  '/ddd': (context, {arguments}) => DDDPage(),
  '/setting': (context, {arguments}) => SettingPage(),
  '/search': (context, {arguments}) => SearchPage(arguments: arguments),
};

//主要方法
var onGenerateRoute = (RouteSettings settings) {
  final String name = settings.name;
  final Function pageContentBuilder = routes[name];
  if (pageContentBuilder != null) {
    if (settings.arguments != null) {
      final Route route =   MaterialPageRoute(builder: (context) =>  pageContentBuilder(context, argumens: settings.arguments));
      return route;
    } else {
      final Route route =  MaterialPageRoute(builder: (context) => pageContentBuilder(context));
      return route;
    }
  }
};

main.dart文件

import 'package:flutter/material.dart';
import 'package:flutter_app01/routes/Routes.dart';

void main() {
  runApp(MyApp());
}

//自定义组件
class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      // home: Tabs(),
      initialRoute: '/', //初始化的时候加载的路由
      onGenerateRoute: onGenerateRoute,

    );
  }
}

16、路由替换/返回根路由

1、替换路由

就是替换当前的页面。

2、返回跟路由

待入的组件表格属性介绍

Form组件

属性名类型说明
keyKey组件在整个Widget树中的key值
autovalidatebool是否自动提交表单
childWidget组件child只能有一个子组件
onChangedVoidCallback当FormFiled值改变时的回调函数

TextFromField组件

属性名类型说明
autovalidatebool自动验证值
initialValueT表单字段初始值
onSavedFormFieldSetter当Form表单调用保存方法Save时回调函数
validatorFormFieldValidatorForm表单验证器

Material Design风格组件

组件名称中文名称简单说明
AppBar应用按钮组件应用的工具按钮
AlertDialog对话框组件有操作按钮的对话框
BottomNavigationBar底部导航条组件底部导航条,可以很容易地在tap之间切换和浏览顶级视图
Card卡片组件带有边框阴影的卡片组件
Drawer抽屉组件Drawer抽屉组件可以实现类似抽屉拉开关闭的效果
FloatingActionButton浮动按钮组件应用的主要功能操作按钮
FlatButton扁平按钮组件扁平化风格的按钮
MaterialAppMaterial应用组件Material App代表使用纸墨设计风格的应用
PopupMenuButton弹出菜单组件弹出菜单按钮
Scaffold脚手架组件实现了基本的Material Design 布局
SnackBar轻量提示组件一个轻量级消息提示组件,在屏幕的底部显示
SimpleDialog简单对话框组件简单对话框组件,只起提示作用,没有交互
TabBar水平选项卡及视图组件一个显示水平选项卡的Material Design组件
TextField文本框组件可接受应用输入文本的组件

MaterialApp

属性名类型说明
titleString应用程序的标题。该标题出现在如下位置:Android:任务管理器的程序快照之上 IOS:程序切换管理器
themeThemeData定义应用所使用的主题颜色。可以指定一个主题中每个控件的颜色
colorColor应用的主要颜色值,即 primary color
homeWidget这个是一个Widget对象,用来定义当前应用打开时,所显示的界面
routesMap<String,WidgetBuider>定义应用中页面跳转规则
initialRouteString初始化路由
onGenerateRouteRouteFactory路由回调函数。当通过Navigator.of(context).pushNamed跳转路由时,在routes查找不到时,会调用该方法
onLocaleChanged当系统修改语言的时候,会触发这个回调
navigatorObserversList导航观察器
debugShowMaterialGridbool是否显示纸墨设计基础布局网格,用来调试UI的工具
showPerformanceOverlaybool显示性能标签

Scaffold

属性名类型说明
appBarAppBar显示在界面顶部的一个AppBar
bodyWidget当前界面所显示的主要内容
floatingActionButtonWidget在Material Design中定义的一个功能按钮
persistentFooterButtonsList在固定在下方显示的按钮
drawerWidget侧边栏组件
bottomNavigationBarWidget显示在底部的导航栏按钮栏
backgroundColorColor背景颜色
resizeToAvoidBottomPaddingbool控制界面内容body是否重新布局来避免底部被覆盖,比如当键盘显示时,重新布局避免被键盘盖住内容。默认值为true

AppBar及SliverAppBar组件

属性名类型默认值
leadingWidgetnull
titleWidgetnull
actionsListnull
bottomPreferredSize Widgetnull
elevationdouble4
flexibleSpaceWidgetnull
backgroundColorColorThemeData.primaryColor
brightnessBrightnessThemeData.primaryColorBrightness
iconThemeIconThemeDataThemeData.primaryIconTheme
textThemeTextThemeThemeData.primaryTextTheme
centerTitlebooltrue

介绍:

属性名说明
leading在标题前面显示的一个组件,在首页通常显示应用的logo;在其他界面通常显示
titleToolbar中主要内容,通常显示为当前界面的标题文字
actions一个Widget列表,代表Toolbar中所显示的菜单,对于通常的菜单,通常使用IconButton来表示,对于不太常用的菜单通常使用PopupMenuButton来显示为三点,点击后弹出二级菜单
bottom通常是TabBar。用来在Toolbar标题下面显示一个Tab导航栏
elevation纸墨设计中组件的z坐标顺序,对于可滚动的SliverAppBar,当SliverAppBar和内容同级的时候,该值为0,当内容咕哝的那个SliverAppBar变为ToolBar的时候,修改elevation
flexibleSpace一个显示在AppBar下方的组件,高度和AppBar高度一样,可以实现一些特殊的效果,该属性通常在SliverAppBar中使用
backgroundColor背景色
brightnessAppBar的亮度,有白色和黑色两种主题
iconThemeAppBar上图标的颜色、透明度和尺寸信息。默认值为ThemeData. primaryIcon Theme
textThemeAppBar上的文字样式
centerTitle标题是否居中显示,默认值根据不同的操作系统,显示方式不一样