一.课前准备
3. 开发工具
Flutter开发工具:VisualStudio Code,Android Studio
移动端开发软件:xcode,Android Studio
二. 课堂目标
*环境搭建
*dart语言及核心库介绍
*http请求
三. 知识点
1. 开发工具介绍
电脑选择:
Windows无法进行ios开发
Mac两端都可以开发,windows电脑不影响flutter的学习
开发工具选择:
Vscode:前端开发啊方便,支持flutter开发,但是无法调试android,可以调试ios手机
Android Studio:android开发必备,同样支持flutter开发(官方推荐)
2. 环境搭建
Mac电脑环境安装
硬件环境,MacOs(64bit)磁盘空间700MB,不包括xcode和androidStudio的磁盘空间,Flutter依赖工具bash,mkdir,rm,git,curl,unzip,which
Step1:使用镜像,(因为网络限制需要设置)
//添加到.bash_profile中,注意,bash_profile是隐藏文件
export PUB_HOSTED_URL = Dart packages
export FLUTTER_STORAGE_BASE_URL = https://storage.flutter-io.cn
注意这个是临时镜像,不能保证一直可以使用,参考详情 using flutter in china以获得有关镜像服务器的最新动态
Setp2:配置Flutter SDK
前往官网获取sdk
解压安装包到想要安装的目录,这个目录放其他盘
cd -/development
unzip -/Downloads/flutter_macos_v0.5.1-beta.zip
添加flutter相关工具到Path中
Export PATH = ‘自己存放路径’/flutter/bin:$PATH
运行flutter doctor 查看安装结果如何
Step3:ios开发环境安装
下载xcode,工具大小8G左右
安装cocopods环境
Step4:android开发环境安装
下载Android Studio
设置android模拟器。。。AndroidStudio>tools>Android>AVDmanager并选择Create Virtual Device
Perference>Plugins安装插件Dart,flutter,安装完成后重启即可
Windows电脑环境安装:
硬件要求:windows7或者更高版本64-bit
Step1:使用镜像,(因为网络限制需要设置)
//添加到.bash_profile中,注意,bash_profile是隐藏文件
export PUB_HOSTED_URL = Dart packages
export FLUTTER_STORAGE_BASE_URL = https://storage.flutter-io.cn
注意这个是临时镜像,不能保证一直可以使用,参考详情 using flutter in china以获得有关镜像服务器的最新动态
Setp2:配置Flutter SDK
前往官网获取sdk
解压安装包到想要安装的目录,这个目录放其他盘,不要装c盘
在Flutter安装目录的flutter文件下找到Flutter_console.bat,双击运行并启动flutter命令行,接下来,就可以在flutter命令行运行flutter命令了
更新变量环境:
控制面板--用户账户,更改我的环境变量
用户变量下检查是否有名为“path”的条目
存在,则追加flutter的全路径,使用分号作为分隔符
如果条目不存在,则创建一个新用户变量Path,将Flutter\bin作为他的值
在用户变量下添加PUB_HOSTED_URL和FLUTTER_STORAGE_BASE_URL条目
重启电脑
安装AndroidStudio 在上边安装Flutter和dart插件,安装完成后重启电脑即可。
第一个flutter程序
Vs Code需要添加flutter和dart code两个插件(file--stting--plugins)安装完成后重启即可
创建flutter项目
方式1:命令行
Flutter create flutterProject
方式2:AdroidStudio
File>New Flutter Project
方式3:Vs Code
View>Command Palette
输入flutter然后选择Flutter.New Project
四. Dart语言基础知识和核心库
变量和常量
//定义变量
var name = ‘Jack’
name = 20 //!数字不能赋值String
print(name); //Jack
var age;
print(age); //null
int height = 12;
print(height); //12
//定义常量
final userName = ‘Jack’;
const pi = 3.14;
注意
(1)被final修饰的顶级变量在第一次声明的时候需要初始化。
(2)被final或者const修饰的变量,变量类型可以省略,建议指定数据类型;
(3)final 和const不能和var同时使用
数据类型
Dart语言常用的数据类型包括:Number,String,Boolean,List,Map.
number类型包含两个子类:int(-2^53-2^53),double(双精度浮点类型)
String类型即字符串类型
Boolean类型(必须为true和false)
List类型,具有一系列相同类型的数据,类型JavaScript中的数组Array对象
Map类型将键和值相关联的对象,键和值都可以是任何类型的对象,每个键只出现一次,但您可以多次使用相同的值
函数
函数也是对象,属于Function对象。函数可以像传参一样传递给其他函数
String getUserInfo(String nam,[int height]){
If(height!=null){
Return name + ‘-height:$height’;
}
Return name;
}
注意:上述getUserInfo中的height参数就是可选的
如果需要给参数设置默认值,则
String getUserInfo(String nam,[int height = 170]){
If(height!=null){
Return name + ‘-height:$height’;
}
Return name;
}
匿名函数
({[Type] param1[, _] }){
codeBlock;
};
//(context)=>HomePage(widget.isDark,themeChanger)
//等价于:func_name (context) {return HomePage(widget.isDark, themeChanger); }
级联符号
Final adddressBook =( AddressBookBuilder()
..name =’jenny’
..email = ‘jenny@Example.com’
..phone = ( PhoneNumberBuilder()
..number = ‘415-555-0100’
..lable = ‘home’)
.build())
.build();
运算符
一元后缀 expr++ expr-- () [] . ?.
一元前缀 -expr !expr ~expr ++expr --expr
乘除 * / % ~/
加减 +-
位移 << >>
按位与 &
按位亦或 ^
按位或 |
关系和类型测试 >= > <= < as is is!
等于 == !=
逻辑与 &&
逻辑或 ||
条件 expr1? expr2: expr3
级联 ..
赋值 = *= /= ~= %= += -= <<= >>= &= ^= ??=
流程控制语句
条件语句 if if...elseif if...elseif...else
//使用for循环
for(var item in list){
print(item);
}
循环语句:while循环,do...while循环
//while 先判断条件再执行
Int i = 0;
while (i<2){
print(i++);
}
//do...while 先执行一次再判断,至少执行一次
do{
print(i--)
}while(i>0 && i<3);
*Break(终止离break最近的循环,只能终止一层循环)continue(跳出当前循环,只能跳出一层循环)
//当i==2时已经终止循环了。
for(var i = 0; i<4; i++){
if (i==2){
break;
}
print(i);
}
//break终止的只是当前的循环,只能终止一层循环
for(var i = 0; i<2; i++){
for(var j = 0;j<4;j++){
If(j==1){
Break;
}
Print(‘[$i,$j]’);
};
};
Switch...case语句
//language 也可以是num,String,编译期常量,对象,枚举这几种类型
String language = ‘java’;
Switch (language){
Case ‘dart’:
print(‘dart language’);
break;
Case ‘java’:
print(‘java language’);
break;
Case ‘python’:
print(‘python language’);
break;
Default:
Print(‘none’);
}
/*用continue跳转到位置执行最近的case*/
Switch (language){
Case ‘dart’:
print(‘dart language’);
break;
Case ‘java’:
print(‘java language’);
Continue TopTest
//break;
Case ‘python’:
print(‘python language’);
break;
TopTest:
Default:
print(‘none’);
}
// 则java language最后输出:none
*比较类型可以有num,String,编译期常量,对象,枚举
*空case必须有一个默认情况
*default处理默认情况
*continue跳转标签
Assert断言
//确保这个变量不为空
assert(text!=null);
//确保这个变量小于100
assert(number<100)
//确保它是一个https协议类型的URL.
assert(urlString.startWih(‘https’));
异常处理
//(1)抛出异常
Throw FormatException(‘抛出一个FormatException异常’);
//你也可以抛出任意对象
Throw ‘数据非法’;
//(2)捕获异常
try{
//逻辑代码操作
}on Exception catch (e){
print(‘exception details:\n $e’);
}catch(){
print(‘exception details:\n $e’);
print(‘stack trace:\n $e’);
}
//(3)finally
try{
//逻辑代码操作
}on Exception catch(e){
print(‘exceptiondetails:\n $e‘);
}catch (e,s){
print(‘exception details:\n $e’);
print(‘stack trace:\n $e’);
}finally{
print(‘Do sth’);
}
面向对象
类的声明,使用class关键字定义类
Class person{
//类成员
String name;
int age;
//final修饰的属性,不能被外部重新赋值,只可读,不可写
final String address = null;
void work(){
Print(‘name is $name,Age is $age’);
}
//dart默认都是公开的,现在变量名或者方法名加_即为私有
void _work(){
print(‘name is $_name,Age is $age’);
}
}
创建对象,使用new关键字或者不写new关键字
var person = Person();
//var person = new Person();
person.name = ‘Tom’;
Person.age = 20;
?
operator重运算符载操作
Class Vector{
Final int x;
Final int y;
const Vector(this.x,this.y);
//重载加号 + (a+b)
Vector operator + (Vector v){
return new Vector(x+v.x, y+v.y);
}
}
Main(){
//实例化两个变量
final result1 = new Vector(10,20);
final result2 = new Vector(30,40);
final result = result1+result2;
Print(‘result.x = ’+result.x.toString()+’’,+’result.y = ’+result.y.toString());
//打印结果
//result.x = 40,result.y = 60
}
继承类:继承它允许创建分等级层次的类继承就是子类继承父类的特征和行为,使得子类具有父类的实例域和方法;
或者子类从父类继承方法,使子类具有和父类相同的行为。Dart里面使用extends关键字来实现继承,super关键字来指定父类。
Class Animal{
Void eat(){
Print(‘动物会吃’);
}
Void run(){
Print(‘动物会跑’);
}
}
Class Human extends Animal{
Void say(){
Print(‘人会说’);
}
Void study(){
Print(‘人会学习’);
}
}
main(){
Var animal = new Animal();
animal.eat();
animal.run();
Value human = new Human();
human.eat();
human.run();
human.say();
human .study();
}
抽象类:不具体实现方法,只是写好定义接口,具体实现留着调用的人去实现,抽象类可以使用关键字abstract来实现。
Absract class Animal{
eat();
run();
printInfo(){
Print(‘我是一个抽象类里面的普通方法’);
}
}
class dog extends Animal{
@override
eat(){
print(‘小狗在吃骨头’);
}
@override
run(){
print(‘小狗在跑’);
}
}
Main(){
Dog d = new Dog();
d.eat();
d.printInfo();
//抽象类没办法直接被实例化
}
Mixins:()相当于多继承,也就是说可以继承多个类,使用with关键字来实现Mixins的功能
Class First{
Void printSth(){
Print(‘im first printSth’);
};
}
Class Scond{
Void printSth(){
Print(‘im second printSth’);
};
Void secondPrint(){
Print(‘test’);
}
}
Class A = Second with First;
main(){
A a = new A();
a.prntSth();
b.secondPrint();
}
//打印结果
// im first printSth
//test
库的使用
通过import语句在一个库中引用另外一个库的文件,需要注意一下事项:
1.在import语句后面需要接上库文件的路径
2.对Dart语言提供的库文件使用Dart:xx格式
3.第三方的库文件使用package:xx格式
import ‘dart:io’;
import ‘package:mylib/mylib.dart’;
3. 指定一个库的前缀
import ‘package:lib1/lib1.dart’;
Import ‘package:lib2/lib2.dart’ as lib2;
Element emelent1 = new Element();//默认使用lib1中的Element
Lib2.Element emelent2 = new lib2.Element(); //使用lib2中的Element
注意:因为都有,需要特别指定lib2.Element
Show关键字,只引用一点
Hide关键字,除此之外都引用
//导入foo
Import ‘package:lib1/lib1.dart’ show foo;
//除了foo导入其他所有内容
Import ‘package:lib1/lib1.dart’ hide foo;
延迟(deferred)加载,也称为延迟lazy加载,允许应用按需加载库
目的:
(1)减少应用程序的初始启动时间
(2)执行A/B测试,尝试的算法的替代实施方式中;
(3)加载很少使用的功能
Import ‘package:deferred/hello.dart’ deferred as hello;
异步支持
Dart是一个单线程编程语言,如果任何代码阻塞线程执行都会导致程序卡死,异步编程防止出现阻塞操作。
Dart使用flutter对象表示异步操作。
Flutter表示在将来某一个时刻获取一个值的方式。当一个返回Future的函数被调用的时候做了两件事:
--函数把自己放入队列,和返回一个未完成的Future对象
--之后当值可用时,Future带着值变成完成状态。
获得Future的方式:()使用asyn和await; ()使用Future的接口
--async和await:async和await关键字是dart异步支持的一部分。允许像写代码一样写异步代码和不需要使用Future接口。
在dart2中有轻微的改动。Async函数执行时,不是立即挂起,而是要执行到函数内部的第一个await.
元数据:又称中介数据,中继数据,为描述数据的数据(data about data),主要是描述数据属性的信息,用来支持如指示存储的位置,历史数据,资源查找,文件记录等功能
(1)使用元数据给代码添加更多的信息
(2)元数据是以@开始的修饰符,在@后面接着编译时的常量或者调用一个常量的构造函数
(3)目前提供的修饰符(@deprecated,@override,@proxy,@required)
4. Http请求
Android设备中网络权限设置:在android\app\src\profile\AndroidManifest.xml中添加如下设置,如下的权限
READ_PHONE_STATE
INTERNET
ACCESS_NETWORK_STATE
ACCESS_WIFI_STATE
1) Pubspec.yam里面需要添加http的依赖
http:^0.12.1
2) 可以使用命令行下载flutter
flutter pub get
3) 导包
Import ‘package:http/http.dart’;
4) 函数使用
方法一:
httpFunction1(){
Var url = ‘htttps://randomuser.me/api/?results=30’;
http.get(url).then((response){
print(‘数据:${response.body}’);
});
}
方法二:
httpFunction2(){
Var httpClient = new HttpClient();
Var url = ‘htttps://randomuser.me/api/?results=30’;
Var request = await httpClient.getUrl(Uri.parse(url));
Var response = await request.close();
Var jsonString = await Respose.transform(utf8.decoder).join();
Print(‘数据:${jsonString}’);
}
2节
课堂目标
Image使用
Text的使用
按钮相关组件
单组件容器布局(Container, Padding, Center, Align)
多组件容器布局 (Row, Column,Stack, Wrap)
手势
ListView的使用
3节-知识点
状态
Stateful 和stateless:实现Flutter app时,我们用widgets来构建app的UI。这些widgets有两种类型--statefue(有状态)和stateless(无状态)
Stateless: 当创建的widget不需要管理任何形式的内部state时,则使用statelessWidget.
eg:Text
Void main() = > runApp(MyStatelessWidget(text:”StatelessWidget Example”));
Class MyStatelessWidget extends StatelessWidget{
Final String text;
MyStatelessWidget({Key key,this.text}):super(Key:key);
@override
Widget build(BuildContext context){
Return Center(
Child:Text(
Text,
textDirection: TextDirection.ltr,
),
);
}
}
Stateful: 当创建一个能随时间动态改变的widget,并且不依赖于其初始化状态,eg:Image
Class FavoriteWidget extends StatefulWidget{
@override
State< StatefulWidget> createState() =>new _FavoriteWidgetState();
}
Class _FavoriteWidgetState extends State{
@override
Widget build(BuildContext context){
Return null;
}
}
注意:
1.创建一个Stateful Widget需要两个类,分别继承自StateFulWidget和State;
2.state对象包含了widget的state和widget的build()方法;
3.当widget的state改变了的时候,state对象会调用setState()方法,告诉框架去重新绘制widget;
常用组件的使用
图片组件image
New Image:从ImageProvider获取图片
New Image.asset:加载资源图片
New Image.file:加载本地文件图片
New Image.network:加载网络图片
New Image.memory:加载Uint8List资源图片
//资源图片
New Image.asset(‘img/logoName.jpeg’),
//网络图片
New Image.network(‘https://flutter.io/images/homepage/header-illustration.png’),
//本地文件图片
New Image.file(new File(‘/User/source/Downloads/imageName.jpeg’)),
//Uint8List图片
Day0923
flutter学习2
App结构和导航组件
MaterialApp应用组件
Scaffold脚手架组件
Flutter主题
可滚动组件
GridView
SingleChildScrollView
Table
App结构和导航组件
MaterialApp:封装了应用程序实现Material Design所需要的一些Widget,实际是一种设计风格,里面会有一些组件(eg:theme)
Title:该属性会在Android应用管理的App上方显示,对于IOS设备是没有效果的
Home:Widget类型,这个是在应用程序正常启动时首先显示阿Widget,除非指定了initialRoute.如果InitailRoute显示失败,也该显示该Widget.
Theme:ThemeData类型,定义应用所使用的主题颜色,可以指定一个主题中每个控件的颜色
Routes:Map<String,WidgetBuilder>类型,是应用的顶级路由表,当使用Navigator.pushNamed进行命名路由的跳转时,会在此路由表中进行查找并跳转
InitialRoute:String类型,初始化路由
OnGenerateRoute:RouteFactory类型,路由回调函数。当通过Navogator.of().pushName跳转的时候,如果routes查找不到会调用这个方法
2. Scaffold
实现了基本的Material Dsign布局结构
AppBar:显示在界面顶部对的一个AppBar
Body:当前界面所显示的主要内容的Widget
Drawer:抽屉菜单控件
BottomNavigationBar:显示在页面底部的导航栏,items必须大于两个
Class MyApp extends StatelessWidget{
@override
Widget Build(BuildContext context){
Return MaterialApp{
Title:’Flutter Demo’
Theme: ThemeData(
primarySwatch:Colors.blue,
),
Home:Scaffold(
appBar:AppBar(
Title:Text(‘首页’),
//centerTitle:false,
),
Drawer:Drawer(
Child:Column(
Children:<Widget>[]
),
),
),
Drawer:Drawer(
Child:Column(
Children:<Widget>[
DrawerItem(1,’选项1’),
DrawerItem(2,’选项2’),
DrawerItem(3,’选项3’),
DrawerItem(4,’选项4’),
DrawerItem(5,’选项5’),
],
),
),
bottomNavigationBar
}}}
3Flutter主题
使用主题可以在App里面共享颜色和字体,在Flutter里面有两种方式来使用主题,一种是全局范围的,一种是使用ThemeWidget,ThemeWidget可以在App的某个部分使用主题。全局的主题其实也就是MateriaApp将Theme作为根Widget了。
ThemeData({
Brightness brightness, //深色还是浅色
MaterialColor primarySwatch, //主题颜色样本
Color primaryColor, //主色,决定导航栏颜色
Color accentColor, //次级色,决定大多数Widget的颜色,如进度条,开关等。
Color CardColor, //卡片颜色
Color dividerColor, //分割线颜色
ButtonThemeData buttonTheme, //按钮主题
Color cursorColor, //输入框光标颜色
Color dialogBackgroundColor, //对话框背景颜色
String fontFamily, //文字字体
TextTheme textTheme, //字体主题,包括标题,body等文字样式
IconThemeData iconTheme, //Icon的默认样式
TargetPlatform platform, //指定平台,应用特定平台控件风格
。。
})
#创建全局主题:MateriaApp接收一个theme的参数,类型为ThemeData,为App提供统一的颜色和字体。支持对的参数可以在这里查看
New MateriaApp(
title:title,
theme:new ThemeData(
Brightness: Brightness.dark,
primaryColor: Colors.lightBlue(800),
),
);
#创建局部主题:如果想为某个页面使用不同于app的风格,可以使用Theme来覆盖App的主题
New Theme(
data:new ThemeData(
accentColor:Colors.yellow,
),
child:new Text(‘Hello World’),
);
#覆盖(扩展)主题:如果不想覆盖所有的样式,可以继承App的主题,只覆盖部分样式,使用copyWith方法。
New Theme(
data:Theme.of(context).copyWith(accentColor:Colors.yellow),
child:new Text(‘use copyWith method’),
);
2:项目开发
1. 配置文件设置
项目中的pubspec.yaml文件
#name很重要,如果修改了name所有的dart的文件的import前引用的本地的文件啊的包名都需要修改name:flutterdemo
Description:A new Fluttter application.
#发布环境
dependencies:
flutter:
sdk:flutter
#添加依赖packages ^表示适配和当前大版本一致的版本,~表示适配和当前小版本一致的版本。
#eg: ^表示适配和当前大版本一致的版本,即2.x.x都可,~表示适配和当前小版本一致的版本,即2.1.x都可
Dio: ^2.1.0
Cupertino_icons: ^0.1.2
English_words: ……3.1.0
# image_picker: ^0.4.8
#本地环境开发
dev_dependencies:
flutter_test:
sdk:flutter
#启用国际化
flutter_localization
sdk:flutter
#数组
Server:
-aaaa
-bbbb
-dddd
#常量
age:22 #int
boolitem: true #定义一个boolean值
name:’hello’ #定义一个sting
Flutter:
//下列声明让你可以使用资源图标
Uses-material-design: true
//添加资源,不单单是图片,images和pubspec.yaml配置文件同等级的目录,如果不同级,需要添加。。
Assets:
- images/park.jpg
-images/lake.jpg
-images/touxiang.jpg
#字体样式
Fonts:
#family与fonts是一个整体,列表对的一项
- famiy:Schyler
Fonts:
-asset:fonts/Schyler-Regular.ttf
-asset:fonts/Schyler-Italic.ttf
Style:italic
-family:Traian Pro
Fonts:
-asset: fonts/TrajanPro.ttf
-asset: fonts/TrajanPro_Bold.ttf
weight:700
注意点:大小写敏感
缩进代表层级,使用空格,默认两个空格(flutter做了处理,tab也可以)
#代表注释内容
:表示键值对,注意后边要空格
{}表示键值表,注意后边要空格
[]表示数组,注意每一项之间有空格
?表示复杂的键