Flutter学习笔记

1、flutter的开始

1、认识文件夹

Flutter学习笔记_第1张图片

文件夹名称 作用
android android平台相关代码
ios ios平台相关代码
lib flutter相关代码,主要编写的代码放入该文件夹
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,
    )
  ));
}

实现效果:

Flutter学习笔记_第2张图片

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,
      ),
    ));
  }
}

实现效果:

Flutter学习笔记_第3张图片

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,
      ),
    ));
  } 
}

实现效果:

Flutter学习笔记_第4张图片

4、组件:Container/Text 详解

1、Container组件

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

Flutter学习笔记_第5张图片

Container组件属性描述

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

2、Text组件

Text组件属性描述

属性名 类型 默认值 说明
data String 数据为要显示的文本
maxLines int 0 文本显示的最大行数
style TextStyle null 文本样式,可定义文本的字体大小、颜色、粗细等
textAlign TextAlign TextAlign.center 文本水平方向对齐方式,取值有center、end、justify、left、right、start、values
textDirection TextDirection TextDirection.ltr 文本书写方向。ltr从左到右,rtl从右到左
textScaleFactor double 1.0 字体缩放系数
textSpan TextSpan null 文本块

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),
      ),
    );
  }
}

效果:

Flutter学习笔记_第6张图片

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组件属性描述

属性名 类型 说明
image ImageProvider 抽象类,需要自己实现获取图片数据的操作
width/hei ght double Image显示区域的宽度和高度设置
fit Boxfit 图片填充模式
color Color 图片颜色
colorBlendMode BlendMode 在对图片进行手动处理的时候,可能会用到图片混合如改变图片的颜色。此属性可以对颜色进行混合处理。
alignment Alignment 控制图片的摆放位置
repeat ImageRepeat 设置图片重复模式
centerSlice Rect 当图片需要被拉伸时使用
matchTextDirection booI 该属性与Directionlity配合使用
gaplessPlayback bool 当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,
        ),
      ),
    );
  }
}

效果:

Flutter学习笔记_第7张图片

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,//************
        ),
      ),
    ));
  }
}

效果:

Flutter学习笔记_第8张图片

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",),
          ),
    ));
  }
}

效果:

Flutter学习笔记_第9张图片

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,),
          ),
    ));
  }
}

效果:

Flutter学习笔记_第10张图片

2、本地图片

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

Flutter学习笔记_第11张图片

2、示例

1、代码

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

2、效果

Flutter学习笔记_第12张图片

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组件的基本属性

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

2、垂直列表

代码:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        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"),
        ),
      ],
    );
  }
}

效果:

Flutter学习笔记_第13张图片

3、水平列表

代码:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      child:ListView(
      scrollDirection: Axis.horizontal,
      children: [
        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,
        ),
      ],
    )
    );
  }
}

效果:

Flutter学习笔记_第14张图片

4、动态列表

代码:

class HomeContent extends StatelessWidget {
  List getData() {
    List 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]),
        );
      },
    ));
  }
}

效果:

Flutter学习笔记_第15张图片

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组件属性及描述

属性名 类型 默认值 说明
scrollDirection Axis Axis.vertical 滚动的方向,有垂直和水平两种,默认为垂直方向
reverse bool false 默认是从上或者左向下或者向右滚动的,这个属性控制是否反向,默认值为false,即不反向滚动
controller ScrollController 控制child滚动时候的位置
primary bool 是否是与父节点的PrimaryScrollcontroller所关联的主滚动视图
physics ScrollPhysics 滚动的视图如何响应用户的输入
shrinkWrap bool false 滚动方向的滚动视图内容是否应该由正在查看的内容所决定
padding EdgeinsetsGeometry 四周的空白区域
gridDelegate SliverGridDelegate 控制GridView中子节点布局的delegate
cacheExtent double 缓存区域

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

代码:

class Demo extends StatelessWidget {
  List getData() {
    List 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(),
    );
  }
}

效果:

Flutter学习笔记_第16张图片

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

代码:

class Demo extends StatelessWidget {
  Widget getData(context, index) {
    return Container(
      child: Column(
        children: [
          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,
    );
  }
}

效果:

Flutter学习笔记_第17张图片

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组件处理容器与子元素之间的间距

属性 说明
padding padding值,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: [
        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,),
        ),
      ],
    );
  }
}

效果:

Flutter学习笔记_第18张图片

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: [
        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,
        ),
      ),
    );
  }
}

效果:

Flutter学习笔记_第19张图片

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: [
        Expanded(
          flex: 1,
          child: IconDemo(
            Icons.home,
            color: Colors.green,
          ),
        ),
        Expanded(
          flex: 2,
          child: IconDemo(
            Icons.search,
            color: Colors.red,
          ),
        ),
      ],
    );
  }
}

效果:

Flutter学习笔记_第20张图片

5、相关案例

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

Flutter学习笔记_第21张图片

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          children: [
            Expanded(
              child: Container(
                height: 200,
                color: Colors.blue,
                child: Text("xxxxxxxxxx"),
              ),
            )
          ],
        ),
        SizedBox(height: 10),
        Row(children: [
          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: [
                    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,
                        ))
                  ]))),
        ]),
      ],
    );
  }
}

效果:

Flutter学习笔记_第22张图片

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: [
        Container(
          height: 400,
          width: 300,
          color: Colors.red,
        ),
        Text("xxxxxxxxxxx")
      ],
    );
  }
}

效果:

Flutter学习笔记_第23张图片

通过alignment属性进行位置移动

Flutter学习笔记_第24张图片

还可以是坐标

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: [
        Container(
          height: 400,
          width: 300,
          color: Colors.red,
        ),
        Text("xxxxxxxxxxx")
      ],
    );
  }
}

效果:

Flutter学习笔记_第25张图片

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: [
        Container(
          height: 400,
          width: 300,
          color: Colors.red,
        ),
        Text("xxxxxxxxxxx"),
        Text("ddddddddddd"),
      ],
    );
  }
}

效果:

Flutter学习笔记_第26张图片

使用align

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 400,
        width: 400,
        color: Colors.blue,
        child: Stack(children: [
          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),
          ), 
        ]),
      ),
    );
  }
}

效果:

Flutter学习笔记_第27张图片

使用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: [
          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),
          ), 
        ]),
      ),
    );
  }
}

效果:

Flutter学习笔记_第28张图片

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 子组件
Shape Card的阴影效果,默认的阴影效果为圆角的长方形边。

代码:

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

效果:

Flutter学习笔记_第29张图片

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相关属性介绍
runAlignment run的对齐方式。run可以理解为新的行或者列,如果是水平方向布局的话,run可以理解为新的一行
runSpacing run的间距

2、wrap实例

代码:

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Wrap(
      spacing:10,
      // runSpacing:5,
      children: [
      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: () {},
    );
  }
}

效果:

Flutter学习笔记_第30张图片

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 {
  int countNum = 0;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(height: 20,),
        Chip(label: Text('${this.countNum}')),
        SizedBox(height: 20,),
        RaisedButton(
          child: Text('按钮'),
          onPressed: (){
            setState(() {
              this.countNum++;
            });
          },
        )
      ],
    );
  }
}

效果:

Flutter学习笔记_第31张图片

13、ButtonNavigationBar组件

1、介绍

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

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

2、实例

1、效果:

底部导航切换页面效果:

Flutter学习笔记_第32张图片

Flutter学习笔记_第33张图片

代码介绍:

Flutter学习笔记_第34张图片

Flutter学习笔记_第35张图片

代码:

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 {
  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 {
  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 {
  @override
  Widget build(BuildContext context) {
    return Container(
       child: Text('HomePage'),
    );
  }
}

14、Flutter中的基本路由

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

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

1、简单路由跳转

Flutter学习笔记_第36张图片

代码:

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

2、跳转传值

Flutter学习笔记_第37张图片

代码:

import 'package:flutter/material.dart';

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

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

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


3、返回

Flutter学习笔记_第38张图片

代码:

import 'package:flutter/material.dart';

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

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

class _SearchPageState extends State {
  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("内容区域"),
    );
  }
}

效果:

Flutter学习笔记_第39张图片

15、Flutter命名路由

1、不携带参数

main.dart文件配置:**

Flutter学习笔记_第40张图片

路由跳转方式:

Flutter学习笔记_第41张图片

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、替换路由

就是替换当前的页面。

Flutter学习笔记_第42张图片

2、返回跟路由

Flutter学习笔记_第43张图片

待入的组件表格属性介绍

Form组件

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

TextFromField组件

属性名 类型 说明
autovalidate bool 自动验证值
initialValue T 表单字段初始值
onSaved FormFieldSetter 当Form表单调用保存方法Save时回调函数
validator FormFieldValidator Form表单验证器

Material Design风格组件

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

MaterialApp

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

Scaffold

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

AppBar及SliverAppBar组件

属性名 类型 默认值
leading Widget null
title Widget null
actions List null
bottom PreferredSize Widget null
elevation double 4
flexibleSpace Widget null
backgroundColor Color ThemeData.primaryColor
brightness Brightness ThemeData.primaryColorBrightness
iconTheme IconThemeData ThemeData.primaryIconTheme
textTheme TextTheme ThemeData.primaryTextTheme
centerTitle bool true

介绍:

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

你可能感兴趣的:(前端基础,flutter,前端)