第1节:iOS项目集成Flutter

本节学习内容:在已有的iOS项目中集成Flutter,以使得您的iOS项目中的部分界面/功能可以通过Flutter来实现。

本节学习用时:30分钟

本节学习方式:动手实践


本节目录:

一、集成方式介绍

二、集成方法一:手动配置iOS与Flutter的混编环境

三、集成方法二:Pod集成Flutter方式

四、集成后调用Flutter界面的代码编写


项目 CQInitProject

一、集成方式介绍

本节将介绍两种在已有的iOS项目中集成Flutter的方法,分别为①手动配置iOS与Flutter的混编环境、②Pod集成Flutter方式。

下面表格是两种集成Flutter的方法比较:

手动集成Flutter Pod集成Flutter
集成速度 需要自己建立文件、进行相应配置,并替换 执行Pod及Run Script即可
Flutter项目更新时 每次都需要替换 不用替换
Flutter项目与iOS同时路径变更时 不影响iOS工程 Flutter工程需要重新编译执行;
然后iOS工程需再重新执行Pod

二、集成方法一:手动配置iOS与Flutter的混编环境

1.1 集成后的最后项目结构如图:

myiosproject project structure

1.2 集成后的最后文件结构如图:

myiosproject file structure

1.3 详细的集成实现步骤如下:
  • ①、通过终端命令在指定目录(这里我们选择iOS项目的同级目录)创建myfluttermodule。flutter create -t module myfluttermodule

  • ②、Xcode:创建iOS项目,设为myiosproject;

  • ③、Xcode:创建配置衔接文件

    • 在②中建立的iOS项目中新建Config目录,用于存放/管理接下来Xcode工程需要创建的的配置衔接文件;

    • 选择创建Configuration Settings File文件,分别创建名为 Flutter.xcconfigDebug.xcconfigRelease.xcconfig的三个配置文件;

      New Configuration Settings File

    • 完善Flutter.xcconfigDebug.xcconfigRelease.xcconfig三个配置文件的内容为分别如下:

      Flutter.xcconfig 配置文件内容如下:

      1
      2
      3
      4
      5
      //Flutter.xconfig,用于指向外目录flutter module的`Generated.xcconfig`文件路径引用文件

      //这里填写前面建立的 myfluttermodule 的Generated.xcconfig的路径
      #include "../../myfluttermodule/.ios/Flutter/Generated.xcconfig"
      ENABLE_BITCODE=NO

      Debug.xcconfig 配置文件内容如下:

      1
      2
      3
      4
      5
      6
      //Debug.xconfig,Xcode的环境配置文件

      #include "Flutter.xcconfig"
      //#include "../Pods/Target Support Files/******.debug.xcconfig"//pod路径
      #include "../Pods/Target Support Files/Pods-myiosproject/Pods-myiosproject.debug.xcconfig"//pod路径
      FLUTTER_BUILD_MODE=debug

      Release.xcconfig 配置文件内容如下:

      1
      2
      3
      4
      5
      6
      //Release.xconfig,Xcode的环境配置文件

      #include "Flutter.xcconfig"
      //#include "../Pods/Target Support Files/******.release.xcconfig"//pod路径
      #include "../Pods/Target Support Files/Pods-myiosproject/Pods-myiosproject.release.xcconfig"//pod路径
      FLUTTER_BUILD_MODE=release
    • 修改Xcode Project的环境配置选择

      myiosproject Project Info Configurations

  • ④、Xcode -> Target -> Build Phases -> New Run Script Phase,添加要执行的脚本内容引入xcode-backend.sh,此步很重要。

    1
    2
    "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
    "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed

    myiosproject New Script xcode-backend.sh

  • ⑤、添加/替换flutter编译产物,如果之前已添加,则这里每次有有新的时候,注意要替换掉,否则界面还是旧的。

    即复制 myfluttermodule/.ios/Flutter下的App.frameworkengineflutter_assets进行替换。

    然后Xcode重新编译即可。

    注意:flutter_assets 并不能使用Create groups 的方式添加,只能使用Creat folder references 的方式添加进Xcode项目内,否则跳转flutter会页面渲染失败(页面空白)。

  • ⑥、至此,恭喜你,到这里您可向往常一样直接执行已集成Flutter的Xcode项目了。

三、集成方法二:Pod集成Flutter方式

2.1 最后的项目结构如图:

myiosproject2 project structure

2.2 实现步骤如下:
  • ①、通过终端命令在指定目录(这里我们选择iOS项目的同级目录)创建myfluttermodule。flutter create -t module myfluttermodule。这里因为我们已经在1中实现,所以不再重复创建。

  • ②、Xcode:创建myiosproject2;添加如Podfile,及在Podfile中如结构图中所示,补充

    1
    2
    flutter_application_path = './../myfluttermodule/'
    eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)

    后,执行pod install

    myiosproject2 pod install

  • ③、Xcode -> Target -> Build Phases -> New Run Script Phase,添加要执行的脚本内容引入xcode-backend.sh,此步很重要。同1中一样的做法。

  • ④、至此,混编环境配置成功!

四、集成后调用Flutter界面的代码编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import "AppDelegate.h"
#import <Flutter/Flutter.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// ViewController *viewController = [[ViewController alloc] init];
// UIViewController *rootViewController = [[UINavigationController alloc] initWithRootViewController:viewController];
UIViewController *rootViewController = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];

return YES;
}

而后,正常执行Xcode项目即可。

三、更多混编

更多混编知识,请查看官网:使用平台通道编写平台特定的代码

platform channel

附:

第5节:Flutter与Dart的升级

一、查看当前Flutter与Dart版本

升级dart sdk和升级flutter sdk是不一样的,两者千万不要搞混了。

废话不多说,其实我就想说一句,dart sdk不建议升级。

为什么这么说呢,原因很简单,因为flutter sdk中自带了匹配flutter sdk版本的dart sdk(flutter sdk和dart sdk的版本要匹配,不是任意的dart sdk版本都能匹配任意的flutter sdk版本,这一点官方已经帮我们做了。在你下载的flutter sdk中就自带了匹配版本的dart sdk)。如果强行手动去升级dart sdk会报错,flutter项目都会出问题的。

flutter与Dart的匹配:https://flutter.cn/docs/development/tools/sdk/releases?tab=macos

1
2
3
4
5
6
7
8
9
qian@qiandeMacBook-Pro ~ % dart --version
Dart SDK version: 2.14.4 (stable) (Wed Oct 13 11:11:32 2021 +0200) on "macos_x64"
qian@qiandeMacBook-Pro ~ %
qian@qiandeMacBook-Pro ~ % flutter --version
Flutter 2.5.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 18116933e7 (6 months ago) • 2021-10-15 10:46:35 -0700
Engine • revision d3ea636dc5
Tools • Dart 2.14.4
qian@qiandeMacBook-Pro ~ %

二、升级到3.0.0

Flutter 3.0 升级涉及的主要三方库整理如下:

三方库 功能简述 当前版本 最新版本 官方开始支持 flutter3.0的版本 备注
pull_to_refresh 下拉刷新上拉加载 2.0.0 2.0.0
flutter_easyrefresh 下拉刷新上拉加载 2.2.1 2.2.1
marquee 跑马灯 2.2.0 2.2.2 2.2.2(5.19)
fading_edge_scrollview 构建具有淡入淡出边缘的可滚动视图 marquee中依赖 2.0.1 2.0.1
photo_manager 相册相关插件 2.0.8 2.1.1 2.1.0+2(5.13)
wechat_assets_picker 相册选择照片 7.2.0 7.3.0 7.3.0(5.13)
wechat_camera_picker 相机拍摄照片 3.1.0 3.2.0+1 3.2.0+1(5.13)
extended_image 图片浏览 6.0.3 6.2.1 6.2.0(5.12)
extended_image_library 图片浏览 3.1.4 3.3.0 3.3.0(5.12)
reorderables 拖曳排序 0.4.4 0.5.0 0.5.0(5.12)
cached_network_image 图片缓存底层库 3.2.0 3.2.1 3.2.1(5.16)
flutter_easyloading loading 3.0.1 3.0.5 3.0.5(5.23)
tim_ui_kit_lbs_plugin 地图位置插件 1.1.2 1.1.2
bruno 贝壳UI库 2.0.0 2.2.0
scroll_to_index 固定/可变行高的滚动 2.1.1 3.0.1 3.0.0
scrollable_positioned_list
scroll_to_index](https://pub.dev/packages/)
scroll_to_index](https://pub.dev/packages/)

上述控件计划处理方案:

1、已支持的,直接升级到,并升级其依赖到的相关库

2、不支持且需要的,进行手动支持,如tim_ui_kit_lbs_plugin

3、不支持但冗余的,合并减少,如pull_to_refreshflutter_easyrefresh

4、不支持但冗余且被其他app使用率不高的,从项目中逐步移除,如bruno

目录

前言

为更好的学习Flutter,特地将Flutter的学习从零整理及总结成本书,方便大家的快速学习!

其他权威网站:Flutter中文网Flutter实战书籍

主流跨平台语言对比

一个推uniapp的flutter、rn、uni-app比较的好文

主流跨平台语言(Flutter和RN、Weex)之间的对比:

主流跨平台语言对比

  • 渲染性能

和RN和Weex将javascript转化为原生控件渲染不同,Flutter完全挣脱了原生控件的“束缚”,如下图所示,Flutter使用了分层架构,分为Framework和Engine两个部分,其中Framework层提供各种基础组件库,包括各种Widget,动画等,Engine层则完全由C和C++实现,使用Skia进行渲染(对!就是chrome用的那个图形渲染框架),官方宣称可以达到原生app的渲染性能。

Flutter结构

  • Google新操作系统Fuchsia(被认为是Android的继任者)也使用Flutter作为其UI框架,今后的发展不可限量。

第1节:Flutter开发环境搭建与运行

本节学习内容:Flutter的环境搭建及创建运行您的第一个Flutter项目。

本节学习用时:30分钟

本节学习方式:动手实践


本节目录:

一、检测您是否具备了Flutter的开发环境

二、创建并运行第一个Flutter项目


一、检测您是否具备了Flutter的开发环境

因为您可能之前已经有配置过Flutter的开发环境了,所以为了避免重复安装,我们通过在终端运行flutter doctor命令,来进行检测,查看是否缺少。

新电脑未安装,请点击查看在macOS上搭建Flutter开发环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 在终端打开该文件
open ~/.bash_profile

# 终端编辑该文件(没有则会新建)
vim .bash_profile # 不存在.bash_profile,可以该终端输入来创建该文件

# 在打开的文件中,插入如下内容
export PATH=`pwd`/flutter/bin:$PATH

# 输入 :wq 来保存


# 在终端执行如下命令,保证设置的环境变量,本次就能够使用
source .bash_profile

1、环境已完善时

如果您的环境之前已经配置过且已完全配置好的话,您的命令执行结果可能会如图所示:

flutter doctor 检测出无问题

2、环境未完善时

  • 如果有提示错误的(如果你是第一次,那肯定有很多问题),请参照本节最后的【附1】、flutter doctor问题解决中的内容进行解决。

分割图1

二、创建第一个Flutter项目

1、最简单的创建Flutter项目的方法

在终端执行flutter create originflutterproject即可在指定目录建立Flutter项目。

flutter create originflutterproject

三、运行Flutter项目

1、运行方法

1.1、查找本地及指定运行设备

1
flutter devices

1.2、常见的在终端运行方法

在指定设备上运行Flutter项目

1
flutter run -d xxxxxxxx

flutter run -d deviceid

1.3、在WebStorm中运行

本质还在flutter run -d xxxxxxxx

如果,你想在WebStorm中运行的话,操作如下:

webstorm flutter run -d deviceid

上述 External Tool的添加过程如下:

1

webstorm flutter run -d deviceid

运行效果如下:

webstorm flutter run -d deviceid

热更新问题:

image-20200817102953555

直接在终端下,输入对应的如r就行。

image-20200817103401865

1.4、在VS Code中运行

选择设备有如下两个地方。当然你也可以直接在终端上执行。

image-20211209225632484

2、运行项目的常见问题

2.1 问题一、缺少第三方库

如果缺少依赖的第三方库,在pubspec.yaml 文件中找到 dependencies 在里面填写 第三方库。

并请在终端执行flutter packages get,以拉取声明的第三方库到本地工程即可。

flutter第三方库官网:https://pub.dartlang.org/

如要了解更多请查看:官网Flutter起步: 体验

分割图1

【附1】、flutter doctor问题解决

flutter doctor该命令的作用:查看是否需要安装其它依赖项来完成安装。

下面涵盖的错误介绍及解决有:

  • 1.1、*-bash: flutter: command not found*
  • 1.2、缺少依赖项
  • 其他问题,请查看【附2】、flutter 安装过程中的其他问题解决

1.1、flutter doctor执行问题-bash: flutter: command not found

原因:Flutter相关命令无效(此时flutter -h肯定也是一样的问题)

附:完好的flutter -h结果应为如图所示:

 flutter -h 检测flutter

解决:下载Flutter SDK,并配置Flutter环境变量到PATH中即可。

步骤:

  • ①下载Flutter SDK。

    Flutter SDK官网地址。(如果您觉得速度慢,这里提供一个已经下载好的地址:Flutter SDK 1.0.0 网盘下载地址 密码:nm09)

  • ②配置Flutter环境变量方法:即在*~/.bash_profile*文件里添加需要配置的内容即可。

    下面是我的~/.bash_profile文件内容:

我的~/.bash_profile

但在这里目前我们只需要上图中我圈出来的那行export PATH=/Applications/flutter/bin:$PATH #配置Flutter环境变量即可。这里我们先满足目前认知Flutter所需的即可,没必要把如下其他行是暂时不需要的所有的都加上去,当然你加上去可以以后更省事。

1
2
3
4
5
6
7
8
9
10
11
# Flutter
export PATH=/Applications/flutter/bin:$PATH #配置Flutter环境变量

# 设置pub源,才能让你在国内愉快的使用别人写的库
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

# ANDROID
export ANDROID_HOME=/Users/lichaoqian/Library/Android/sdk #android sdk目录,替换为你自己的即可
export PATH=${PATH}:${ANDROID_HOME}/tools
export PATH=${PATH}:${ANDROID_HOME}/platform-tools

1.2、flutter doctor执行结果问题:缺少依赖项

如果您不缺依赖项,那您命令的执行结果会为

如果flutter doctor 检测出问题,此时的命令执行结果一般如下:

flutter doctor 检测出问题

原因:缺少依赖项

解决:遇到什么错误,根据提示操作即可。

1.2.1、iOS toolchain

image-20220321005147057

①、解决iOS toolchain - develop for iOS devices (Xcode 10.1),根据提示终端执行命令后iOS toolchain即变为正常如下

iOS toolchain问题解决后

1.2.2、Android toolchain

②、解决Android toolchain - develop for iOS devices

image-20220321005213102

在遇到这个问题,首先要确保自己的Android studio的下图中的几个项勾选上:

image-20220321010157585

安装 Android SDK Command-line Tools(latest)

image-20220321010247340

根据提示下载Android SDK,并放置ANDROD_HOME指定的目录下后,问题解决,结果如下:

Android SDK安装后

其他参考:入门: 在macOS上搭建Flutter开发环境

修改环境变量:

1
2
3
4
# ANDROID
export ANDROID_HOME=/Users/qian/Library/Android/sdk #android sdk目录,替换为你自己的即可
export PATH=${PATH}:${ANDROID_HOME}/tools
export PATH=${PATH}:${ANDROID_HOME}/platform-tools

非M1芯片的Mac:

image-20220321011753288
1.2.3、Android Studio

③、解决Android Studio

image-20220321005253299

为Android Studio安装Flutter Plugins后

Android Studio安装Flutter Plugins后

安装过程中,如遇Plugins搜索不到时候,如

Android Plugins搜索不到的示例截图

请确保如下图中的路径Perferences -> Appearance & Behavior -> System Settings -> Updates -> Use secure connection中的勾是取消的,如果不是请取消掉,并重启Android Studio后,重新搜索即可。

Android Plugins搜索不到的处理1

或者可以直接从http://plugins.jetbrains.com/上下载插件后,通过选择插件安装方式为Install plugin from disk来进行安装,如下图:

插件安装方式选择为Install plugin from disk

附:这是已经下载好后存在网盘上的Flutter插件

1.2.4、解决Intelij IDEA,为Intelij IDEA安装Flutter Plugins后

④为Intelij IDEA安装Flutter Plugins后的结果,即为不缺依赖的情况了。

其他资料:官网中的入门: 在macOS上搭建Flutter开发环境

如果还没解决安装问题,请查看【附2】、flutter 安装过程中的其他问题解决

四、升级 Flutter

官网升级 Flutter的标准步骤

1.2.5、解决Flutter

有时候,你还会有这种错误,原因为你的flutter sdk太旧了。

flutter doctor 检测出问题2

官网下载最新sdk,并替换掉你之前的flutter sdk。(附:你之前的Flutter的sdk的路径,请通过你写在open ~/.bash_profile中的PATH找到。

image-20200717193444530

【附2】、flutter 安装过程中的其他问题解决

flutter doctor其他问题1

原因:您的Flutter SDK 要求你Android Studio中的Flutter plugin版本至少到16.0.0。但你当前的Android Studio版本却只允许你最高只能装到Flutter plugin version 12.1。

解决:升级你的Android Studio后,重新安装其Flutter plugin。

【附3】、flutter 运行的过程中的其他问题解决

image-20200718010926592

可以看出是路径出错了。

根据路径出错这个方向,进行工程配置错误的查看,发现出错的位置在如下图位置。

image-20200718011513227

假设我们的工程目录结构如下,

image-20200718012410466

则cj_nativeflutter_fluttermodule的路径表示为${SRCROOT}/../cj_nativeflutter_fluttermodule

修改完后,重新编译即可解决问题。

Command PhaseScriptExecution failed with a nonzero exit code

image-20200718014117212

pubspec.yaml文件所在的目录下执行flutter packages get

flutter packages get获取pubspec.yaml文件中列出的所有依赖包

image-20200718014656554

接着再执行flutter packages upgrade,会发现刚才的Compiler message错误少了很多

flutter packages upgrade 获取pubspec.yaml文件中列出的所有依赖包的最新版本

更新库之后还有错误。

image-20200718015310060

进入工程查看,确实各个地方都提示着我们工程代码有问题。那么我们所需要做的就是修复这个问题。

image-20200718015625741

我们对这些编译不通过的代码进行修复或者临时注释掉,即可通过。

第3节:Flutter的最基础知识

本节学习内容:通过最基础的Flutter控件等实现一个app ,让您对Flutter构建的app有一个初步的认识!

本节学习用时:30分钟

本节学习方式:推荐直接看懂代码即可


本节目录:

一、本节内容介绍

二、本节代码解释


一、本节内容介绍

本节通过实现以下界面/功能效果,为您介绍一些最基础的Flutter知识点。

1、主要介绍的知识点有:

  • MaterialApp的应用
  • Scaffold的应用
  • 文本的应用:Text
  • 按钮的应用:FloatingActionButton
  • 页面的跳转

2、要实现的效果如下图所示:

materialappproject效果图

3、实现本节效果的代码

本节所有代码文件为:main.dartNewRoute.dart

您可自己通过flutter create materialappproject创建materialappproject项目后,将其lib文件夹下的代码文件替换为如下即可。

3.1、其中完整的main.dart代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import 'package:flutter/material.dart';
import 'NewRoute.dart';

// 写法①
// >>>>>>>>>>>>> runApp写法① >>>>>>>>>>>>>
// void main() {
// runApp(new MaterialApp(
// title: '1.MaterialApp in main',
// home: new HelloWorldPage(),
// ));
// }
// <<<<<<<<<<<<< runApp写法① <<<<<<<<<<<<<


// 写法②
// >>>>>>>>>>>>> runApp写法② >>>>>>>>>>>>>
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '2.MaterialApp in MyApp',

// 页面跳转的方式②:注册路由表
// 详情查看[官网路由管理](https://book.flutterchina.club/chapter2/flutter_router.html)
// 缺点:路由传递的参数无法动态修改(如果路由有参数)
routes: {
"new_page": (context) => NewRoute(),
},

home: HelloWorldPage(),
);
}
}
// <<<<<<<<<<<<< runApp写法② <<<<<<<<<<<<<


class HelloWorldPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
//Scaffold是Material中主要的布局组件.
return new Scaffold(
appBar: new AppBar(
leading: new IconButton(
icon: new Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null,
),
title: new Text('MaterialApp Example title'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
//body占屏幕的大部分
body: new Center(
child: new Text('Hello, world2!'),
),
floatingActionButton: new FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: new Icon(Icons.add),
// 1、无方法
// 写法①
// onPressed: null,
// 写法②
// onPressed: () {}
// 写法③
// onPressed: () => {}

// 2、有方法,但该方法无参数
// 写法①
// onPressed: printLog,
// 写法②
// onPressed: () {
// printLog();
// },

// 3、有方法,且该方法有参数
// onPressed:() {
// printText("Hello world");
// }

// 4.页面跳转方式
// 写法①
// onPressed: () {
// goNextPage(context);
// },
// 写法②
// onPressed: () {
// Navigator.pushNamed(context, "new_page");
// },
// 写法③
onPressed: () {
Navigator.push(context, new MaterialPageRoute(builder: (context) {
return new NewRoute();
}));
},
)
);
}
}

void printLog() {
print("This is printLog Method");
}

void printText($text) {
print("The text is " + $text);
}

void goNextPage(context) {
// 导航到新路由
Navigator.push(context, new MaterialPageRoute(builder: (context) {
return new NewRoute();
}));
}

3.2、其中完整的NewRoute.dart代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import 'package:flutter/material.dart';

class NewRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New route"),
),
body: Center(
child: Text("This is new route"),
),
);
}
}

二、本节代码解释

1、MaterialApp的使用方式介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 写法①
import 'package:flutter/material.dart';

void main() {
runApp(new MaterialApp(
title: '1.MaterialApp in main',
home: new HelloWorldPage(),
));
}


// ------------------- 我是分割线,下面介绍的是另一种写法 ------------------- //
// 写法②
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '2.MaterialApp in MyApp',
home: HelloWorldPage(),
);
}
}

2、Scaffold的使用方式介绍

以创建一个新页面NewRoute.dart为例,该文件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import 'package:flutter/material.dart';

class NewRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New route"),
),
body: Center(
child: Text("This is new route"),
),
);
}
}

3、文本Text以及按钮Button的使用介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class HelloWorldPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
//Scaffold是Material中主要的布局组件.
return new Scaffold(
appBar: new AppBar(
leading: new IconButton(
icon: new Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null,
),
title: new Text('MaterialApp Example title'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
//body占屏幕的大部分
body: new Center(
child: new Text('Hello, world2!'),
),
floatingActionButton: new FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: new Icon(Icons.add),
onPressed: null,
),
);
}
}

三、按钮Button

按钮的点击:略,请看前文

四、新页面的创建

以创建一个新页面NewRoute.dart为例,该文件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import 'package:flutter/material.dart';

class NewRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("New route"),
),
body: Center(
child: Text("This is new route"),
),
);
}
}

五、页面的跳转 & 路由的管理

页面的跳转,略。请看前文

第3节:Flutter的最基础知识

一、最基础知识

1、颜色

1
2
Colors.transparent,  //透明色
Colors.black.withOpacity(0.4)

2、图片

1
new Image.asset('images/goods_image.png', width: 30.0, height: 30.0,),

三、按钮Button

1、按钮形式

1
2
3
4
5
6
7
8
9
floatingActionButton: new FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: new Icon(Icons.add),
// 点击进行页面跳转
onPressed:() {
goNextPage(context);
}
),
);

2、按钮的事件写法

2.1、无方法
1
2
3
4
5
6
7
8
9
// 写法①
onPressed: null,

// 写法②:推荐
onPressed: () {}

// 写法③:不推荐
onPressed: () => {}
// 缺点:只能直接retrun返回值,不能写多行
2.2、有方法,但该方法无参数
1
2
3
4
5
6
7
8
9
10
11
12
// 设方法为:
void printLog() {
print("This is printLog Method");
}

// 则按钮点击事件有两种写法:
// 写法①:常见的写法
onPressed: () {
printLog();
},
// 写法②:简写
onPressed: printLog,
2.3、有方法,且该方法有参数
1
2
3
4
5
6
7
8
//设方法为:
void printText($text) {
print("The text is " + $text);
}
//则按钮点击事件为:
onPressed:() {
printText("Hello world");
}

五、页面的跳转 & 路由的管理

5.1 直接跳转

以跳转到上述建立的NewRoute.dart为例,则跳转方法:

方式①:

1
2
3
4
5
6
7
8
import 'NewRoute.dart';

// 按钮处的写法
onPressed: () {
Navigator.push(context, new MaterialPageRoute(builder: (context) {
return new NewRoute();
}));
},

方式②:

1
2
3
4
5
6
7
8
9
10
11
12
13
import 'NewRoute.dart';

// 定义导航到新路由的方法
void goNextPage(context) {
Navigator.push(context, new MaterialPageRoute(builder: (context) {
return new NewRoute();
}));
}

// 则按钮处的写法,自然如下:
onPressed:() {
goNextPage(context);
}

5.2 使用路由管理

1
2
3
4
5
6
7
8
9
10
11
import 'NewRoute.dart';

// 在MaterialApp中注册路由表
routes: {
"new_page": (context) => NewRoute(),
},

// 按钮位置写法
onPressed: () {
Navigator.pushNamed(context, "new_page");
},

第2节:Flutter的Hello World

本节学习内容:分别通过多种方法实现Hello world! ,让您对Flutter有一个初步的认识!

本节学习用时:3分钟

本节学习方式:推荐直接看懂代码即可


本节目录:

一、本节内容介绍

二、本节代码解释


一、本节内容介绍

1、本节代码

本节所有代码文件为:main.dart

您可自己通过flutter create helloworldproject创建helloworldproject项目后,将其lib文件夹下的代码文件替换为如下即可。

1.1、其中完整的main.dart代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import 'package:flutter/material.dart';

// 方法①
// >>>>>>>>>>>>> start >>>>>>>>>>>>>
// void main() => runApp(const Center(
// child: Text('1.Hello, world! in Main', textDirection: TextDirection.ltr)));
// <<<<<<<<<<<<< end <<<<<<<<<<<<<


// 方法②
// >>>>>>>>>>>>> 方法② >>>>>>>>>>>>>
// void main() => runApp(MyApp());

// class MyApp extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// return const Center(
// child: Text('2.Hello, world! in MyApp return!', textDirection: TextDirection.ltr));
// }
// }
// <<<<<<<<<<<<< 方法② <<<<<<<<<<<<<


// 方法③
// >>>>>>>>>>>>> 方法③ >>>>>>>>>>>>>
// void main() => runApp(MyApp());

// class MyApp extends StatelessWidget {
// helloWorldPage() {
// return Center(
// child: Text('3.Hello world! in helloWorldPage',
// textDirection: TextDirection.ltr),
// );
// }

// @override
// Widget build(BuildContext context) {
// return helloWorldPage();
// }
// }
// <<<<<<<<<<<<< 方法③ <<<<<<<<<<<<<


// 方法④
// >>>>>>>>>>>>> 方法④ >>>>>>>>>>>>>
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return HelloWorldPage();
}
}

class HelloWorldPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('4.Hello world! in HelloWorldPage',
textDirection: TextDirection.ltr),
);
}
}
// <<<<<<<<<<<<< 方法④ <<<<<<<<<<<<<

2、代码说明