第一部分 vscode终端操作快捷键腾讯文档
第二部分 hello world程序
第三部分 常用组件
注意:由于现在flutter在中国还不够流行,文档和教程少一些,大部分时间只能看官方英文文档,不利于入门,所以我自己整理了一些表格用来记录组件和类,主要是为了方便自己日后查用。由于是自己整理的,属性方法都不是很全,我会一直更新此表格。也会更新到此文中。
我的文档地址(目前不完善,会持续更新):
第一部分 vscode终端操作快捷键:
运行模拟器:flutter run
更新页面:R
显示网格:P
android/IOS模式切换:O
关闭终端:Q
热更新方法:用debug,按照VS的提示配置即可,配置完成后 如下
![v2-d25cd22462380c96759dbbc50e97618f_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/48c7ac32b215de19f672709ace870060.jpeg)
第二部分. 框架简介及hello world
一、总体架构
1、总体架构
![v2-f5bc2c2ec8e6aa70ad75b93895a008ed_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/bec73821147f5278cdd9e749d3896954.jpeg)
其中engine部分 :
* skia 图形UI框架
* dart 虚拟机dartVM
* text 渲染纹理
其中Framework部分:
+ foundation:功能接口
+ animation: 动画
+ painting:图像
+ gestures:触控
+ rendering:渲染
+ widgets:组件
+ meterial:googleUI风格
+ cupertino:IOSUI风格
2、GPU渲染
![v2-bf81c125af35fd0401d1e196d5aaee18_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/964914052e86daf8e466cf3238bd6a26.jpeg)
3.状态控制
![v2-f2b5f3def23bc7f859614fa063419fed_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e844b2295d8b236148cda13be0044cbf.jpeg)
4.Flutter理论基础知识
二、写一个hello world程序
主程序在main.dart里
![v2-460759975a83b9f7f5232c3169565593_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/ca3239d57a1efdc0ae72ffcec4411339.png)
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APP
class MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象
@override //重构build方法
Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件
return MaterialApp( //返回方法 返回组件
title: "welcome", //APP的title
home: Scaffold( //APP的主体,其类型是一个脚手架Scaffold
appBar: AppBar( //脚手架第一个组成是appbar
title: Text("welcome to big bear's flutter!!!"), //appbar的title
),
body: Center( //脚手架的第二个组成是body 给body一个center组件做内容
child: Text("hello 熊爸haha!"), //center里有一个子组件是 Text("???")
),
),
);
}
}
![v2-35e71eb728d0d5b95677e2fdc1f6acd5_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/82ccbf90036466419b2feb15b26cccbb.png)
第三部分 常用组件
statelesswidget 无状态变化的组件
statefullwidget 有状态变化的组件
一、文字组件 Text("")
![v2-9c4e4b8e66574cd4c0390ba173a348e4_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/40d9623c397529a8c15affe229eef6d1.png)
1.textAlign (文本对齐)
Text的子属性,可传入TextAlign类对象,比如:
TextAlign.left 左对齐
TextAlign.right 右对齐
TextAlign.start 和文字开始对齐
TextAlign.end 和文字结束对齐
![v2-d7340fbede16f1faf035f13abc5ea2ca_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e82c1a5e4a8b705ca8a58a0427eb341f.png)
2. maxLines (最大显示行数)
Text的子属性,可传入数值
Text(
"hello 熊爸haha!锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。",
textAlign: TextAlign.end,
maxLines: 1,
)
3. overflow 溢出处理
Text的子属性,可传入TextOverflow类对象
![v2-f9cc1023237443b52438995a2ff24686_b.png](https://i-blog.csdnimg.cn/blog_migrate/0e465ee2cda8bf0ff3bc2f672c441bae.png)
4. style 文字样式
Text的子属性,可传入TextStyle类对象
TextStyle类对象:
![v2-7fd67286d3e9bb6efabfcd73dcb23f0e_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/ce7ff49c3b0e94f43200f9c845be8c81.jpeg)
![v2-d189f96c74d0f163ee97090ba0c9c74a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/3cc78afd8024be0c8e7801b7c1b9da1d.png)
![v2-5a683330d9a707a35ef1c316e49774cb_b.png](https://i-blog.csdnimg.cn/blog_migrate/e402745a24d3915c648e2ed1d59e8a1b.png)
![v2-9d5652bc350005ce7db847b1cfdab50f_b.png](https://i-blog.csdnimg.cn/blog_migrate/6249bb377870314cc2edace1e59fd3d0.png)
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APP
class MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象
@override //重构build方法
Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件
return MaterialApp( //返回方法 返回组件
title: "welcome", //APP的title
home: Scaffold( //APP的主体,其类型是一个脚手架Scaffold
appBar: AppBar( //脚手架第一个组成是appbar
title: Text("welcome to big bear's flutter!!!"), //appbar的title
),
body: Center( //脚手架的第二个组成是body 给body一个center组件做内容
child: Text(
"hello 熊爸熊爸熊爸haha!锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。",
textAlign: TextAlign.left,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 25.0,
color:Color.fromARGB(255, 220, 125, 125),
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.wavy,
),
), //center里有一个子组件是 Text("???")
),
),
);
}
}
![v2-45fd2f0177bac8c05f384454f478a627_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/6a34ccc6d20dc1e19de8e68675aa655a.png)
二、container组件 container() 容器
container() 相当于HTML里的div
![v2-9f39fbccabc2cfed8bdd959621a41faf_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/7730a72c5fc35b929bf219b8776dce90.jpeg)
![v2-f51fc1cbc9125e673d81865de7c6e7fe_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/ed58a14c5f1c339428662a1e96b0163e.png)
![v2-e6725725a515262322ab3ac698a41499_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/8c4f4c55ed864ce76e803bfa55c2911b.jpeg)
![v2-96334261de7908bb18020e7fbebb2293_b.png](https://i-blog.csdnimg.cn/blog_migrate/7f81e724eeda77e4db18dcfc881cfa7f.png)
![v2-8b1e52183ed15dce69ecd2cb8c00f2c8_b.png](https://i-blog.csdnimg.cn/blog_migrate/c3f4734af8f30e2eb79b18c90bc61486.png)
![v2-e410009b39f13e3456b36b35124752d6_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/a89b07bf6ce3d98a962def17b8dd629e.jpeg)
![v2-c09304b5c9399626465f6372876a9869_b.png](https://i-blog.csdnimg.cn/blog_migrate/b2f854000bc1ff7e41e86772643096d7.png)
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APP
class MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象
@override //重构build方法
Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件
return MaterialApp( //返回方法 返回组件
title: "welcome", //APP的title
home: Scaffold( //APP的主体,其类型是一个脚手架Scaffold
appBar: AppBar( //脚手架第一个组成是appbar
title: Text("welcome to big bear's flutter!!!"), //appbar的title
),
body: Center( //脚手架的第二个组成是body 给body一个center组件做内容
child: Container(
height: 400.0,
width: 300.0,
//color: Colors.pinkAccent,
margin: EdgeInsets.symmetric(horizontal: 010.0),
decoration: new BoxDecoration(
gradient: const LinearGradient(colors: [Colors.lightBlue,Colors.green],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
tileMode: TileMode.clamp,
),
border: Border.all(width: 2.0,color: Colors.blueGrey),
),
transform: Matrix4.rotationZ(0.1),
alignment: Alignment.topLeft,
padding: const EdgeInsets.fromLTRB(15.0, 30.0, 15.0, 0),
child: Text(
"锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦!",
style: TextStyle(
fontSize: 24.0,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
),
), //center里有一个子组件是 Text("???")
),
),
);
}
}
![v2-ee982818700d0d8d521880b7072d5c0b_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/c6380196572f2afd8a878e1f63d61fcb.jpeg)
三 image组件
![v2-32f074f13e0d7ad4757e55573ac0f31e_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/50c557930bb9abf23a2fdeeae81a47ec.png)
![v2-5079aead053db66fb118e75c610a6993_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/1e262988fad23896531a9f300114446c.png)
![v2-e016f2b3ef2fef4e30968216e6543dd9_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/d584f46339801d8b54cf646075f5be6a.jpeg)
![v2-1ad941099a03fed3fe4fe2d43b942b73_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/417853be54c03eba2fa71f354808b61e.png)
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APP
class MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象
@override //重构build方法
Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件
return MaterialApp( //返回方法 返回组件
title: "welcome", //APP的title
home: Scaffold( //APP的主体,其类型是一个脚手架Scaffold
appBar: AppBar( //脚手架第一个组成是appbar
title: Text("welcome to big bear's flutter!!!"), //appbar的title
),
body: Center( //脚手架的第二个组成是body 给body一个center组件做内容
child: Container(
height: 600.0,
width: 400.0,
color: Colors.lightBlue,
child: Image.network(
"http://cms-bucket.ws.126.net/2019/1228/d84b26e0p00q37jrh002uc0009c005uc.png?imageView&thumbnail=200y140",
fit: BoxFit.scaleDown,
repeat: ImageRepeat.repeat,
color: Colors.pinkAccent,
colorBlendMode: BlendMode.darken,
)
),
),
),
);
}
}
四 listView组件 列表布局
ListView的children是组件类型,所以可以随便添加任意组件
![v2-3a4e0a8f42d0385ecf749225422a7e12_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/90f4f6113da2b020fd9c6f0d89a34fd7.png)
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APP
class MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象
@override //重构build方法
Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件
return MaterialApp( //返回方法 返回组件
title: "welcome", //APP的title
home: Scaffold( //APP的主体,其类型是一个脚手架Scaffold
appBar: AppBar( //脚手架第一个组成是appbar
title: Text("welcome to big bear's flutter!!!"), //appbar的title
),
body: Center(
child: Container(
height: 200,
color: Colors.pinkAccent,
child: MyList001(),
),
)
),
);
}
}
class MyList001 extends StatelessWidget{
@override
Widget build(BuildContext context) {
return ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(width: 180,color: Colors.lightBlue,),
Container(width: 180,color: Colors.pinkAccent,),
Container(width: 180,color: Colors.lightGreen,),
Container(width: 180,color: Colors.deepPurple,),
],
);
}
}
动态列表(参数传递内容的列表)
import 'package:flutter/material.dart';
void main() => runApp(MyApp(
items:List<String>.generate(15,(i)=>"Item $i") //在myapp类里创建了一个属性叫items,它里面有一个列表
//里面的(i)=>"Item $i"是自动生成列表的项,就像python 列表中可以写lambda表达式一样
));
class MyApp extends StatelessWidget{
final List<String> items; //类中建立属性items
MyApp({Key key,@required this.items}):super(key:key);
//Key key 重写构造函数默认传入的
//@required this.items 限定修饰 this.items必须传入
//:super(key:key) 调用祖先/父类无名无参构造函数,StatelessWidget 所以需要super往上找
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Scaffold(
body:ListView.builder( //用专门的builder方法构建动态列表
itemCount: items.length, //传入项目的数量
itemBuilder: (context,index){ //传入context上下文,同时传入index
//这里有点像JS,把下文中需要的参数实现一下
return ListTile( //listTile listview的项目瓦片
title: Text("${items[index]}"), //通过重构函数,我们将外部的信息传入了动态列表中
);
},
)
),
);
}
}
五 网格列表布局
![v2-99cdbd023ffa490188e0780f123dda7a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/2cff76edea4bc79aa314d4008087c6f5.jpeg)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Scaffold(
appBar: AppBar(
title: Text("dasdasdas"),
),
body:MyGridList(),
),
);
}
}
class MyGridList extends StatelessWidget{
@override
Widget build(BuildContext context) {
return GridView.count(
padding: EdgeInsets.all(5.0),
crossAxisSpacing:5,
crossAxisCount: 3,
mainAxisSpacing: 5,
childAspectRatio: 0.7,
children: <Widget>[
Image.network("https://image11.m1905.cn/uploadfile/2019/0829/thumb_1_150_203_20190829041446876955.jpg",fit: BoxFit.cover,),
Image.network("https://image11.m1905.cn/uploadfile/2019/1227/thumb_1_150_203_20191227090512473043.jpg",fit: BoxFit.cover,),
Image.network("https://image11.m1905.cn/uploadfile/2019/0123/thumb_1_150_203_20190123044311875088.jpg",fit: BoxFit.cover,),
Image.network("https://image11.m1905.cn/uploadfile/2018/0209/thumb_1_150_203_20180209015612332245.jpg",fit: BoxFit.cover,),
Image.network("https://image11.m1905.cn/uploadfile/2014/0812/thumb_1_150_203_20140812031906771224.jpg",fit: BoxFit.cover,),
Image.network("https://image11.m1905.cn/uploadfile/2009/1106/thumb_1_150_203_20091106112530726.jpg",fit: BoxFit.cover,),
Image.network("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2577327061.webp",fit: BoxFit.cover,),
Image.network("https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2578045524.jpg",fit: BoxFit.cover,),
Image.network("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2556824333.jpg",fit: BoxFit.cover,),
Image.network("https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2574764569.jpg",fit: BoxFit.cover,),
Image.network("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2568258113.jpg",fit: BoxFit.cover,),
Image.network("https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2541280047.jpg",fit: BoxFit.cover,),
],
);
}
}
六.按钮组件
![v2-fc8bec7497272ebc3ed026eefedef49e_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/96fab019aec8062bd70dff0d8e19cdfe.jpeg)
七.水平布局
Row组件水平布局,搭配Expanded组件 可实现灵活的水平布局
对Row来说 主轴是水平方向
![v2-c06e719d60ac4148382b9d05819b75b8_b.png](https://i-blog.csdnimg.cn/blog_migrate/470843fa1cec1f0f23f9dd92c01acafd.png)
![v2-fec604492e3031744ca1bd0a2768d9f2_b.png](https://i-blog.csdnimg.cn/blog_migrate/9bcb39ab4e2d1234eb0bceab1a60c3c5.png)
![v2-a07cdae9f0869d756d5b8c2076830595_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/7cefefa1db24717c1df3dd2591f38557.png)
![v2-d77c7aa4d488a4d7001e611dfcd13d60_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e8907cb84befd60bc3f15b9253db34a1.jpeg)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Scaffold(
appBar: AppBar(
title: Text("熊爸"),
),
body:Row(
children: <Widget>[
RaisedButton(
onPressed: (){print("点击了");},
color: Colors.amberAccent,
child: Text("amberAccent"),
),
Expanded(child: RaisedButton(
onPressed: (){print("点击了");},
color: Colors.lightBlue,
child: Text("lightBlue"),
),),
Expanded(child: RaisedButton(
onPressed: (){print("点击了");},
color: Colors.pinkAccent,
child: Text("pinkAccent"),
),)
],
),
),
);
}
}
八 垂直布局
![v2-c55573754f77e87221e1211e0e595bf2_b.png](https://i-blog.csdnimg.cn/blog_migrate/cae6ea35a1b800e782a0bb090e675454.png)
对Row来说 主轴是垂直方向
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Scaffold(
appBar: AppBar(
title: Text("熊爸"),
),
body:Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("熊爸"),
Expanded(child: Text("锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。"),),
Text("data"),
],
),
),
);
}
}
九 Stack组件、Position组件(层叠布局 )
两层堆叠用Stack组件
多层堆叠用Position组件
![v2-056f24a57d5f414b9b20aee34ba5c749_b.png](https://i-blog.csdnimg.cn/blog_migrate/21e9fde0ccc74c9efa670b70faf643cc.png)
![v2-9713ff0910f745f102d7605bf5cd7568_b.png](https://i-blog.csdnimg.cn/blog_migrate/f669ee43117c86afd441c38a40ce09ce.png)
![v2-d6e8916c85c294a692030aad2c3f285a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/779752f3b5c0aae6fffd7c3ace5b4221.png)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Scaffold(
appBar: AppBar(
title: Text("熊爸"),
),
body:Stack(
alignment: FractionalOffset(0.5,0.9),
children: <Widget>[
CircleAvatar(child: Text("一部电影"),radius: 200,foregroundColor: Colors.purple,backgroundImage: NetworkImage("https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2578045524.jpg"),),
Container(
width: 100,
height: 50,
color: Colors.lightBlue,
alignment: Alignment.center,
child: Text("本月最佳",style: TextStyle(color: Colors.white),),
)
],
),
),
);
}
}
![v2-223d228853621d4e6b1170e9c73956fb_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/53f6448df677035c8d7729c59245e9f6.jpeg)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Scaffold(
appBar: AppBar(
title: Text("熊爸"),
),
body:Stack(
alignment: FractionalOffset(0.5,0.9),
children: <Widget>[
CircleAvatar(child: Text("一部电影"),radius: 200,foregroundColor: Colors.purple,backgroundImage: NetworkImage("https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2578045524.jpg"),),
Positioned(
top: 10.0,
left: 20.0,
child: Text("haha")
),
Positioned(
bottom: 10.0,
right: 20.0,
child: Text("OKOK")
),
],
),
),
);
}
}
十 圆盘组件
![v2-6bb7c1418e409b56d2e95ca39fea9433_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/3decb01f245815fc1cd388483f16e1ca.jpeg)
十一 瓦片组件
![v2-0d6909d06b7d4a802761757c510ad8f1_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/bb76cfc1af460ac0e4d925ec703c6956.jpeg)
十二 卡片布局
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Scaffold(
appBar: AppBar(
title: Text("熊爸"),
),
body:Card(
borderOnForeground: true,
child: Column(
children: <Widget>[
ListTile(
title: Text("anny baby",style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold),),
subtitle: Text("a lovely girl"),
leading: CircleAvatar(backgroundImage: NetworkImage("https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2572847101.webp"),),
),
Divider(),
ListTile(
title: Text("anny baby",style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold),),
subtitle: Text("a lovely girl"),
leading: Icon(Icons.satellite),
trailing: Icon(Icons.keyboard_arrow_right),
),
Divider(),
ListTile(
title: Text("anny baby",style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold),),
subtitle: Text("a lovely girl"),
leading: Icon(Icons.satellite),
),
],
),
),
),
);
}
}
十三 分割线组件
Divider()
十四 导航
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: "welcome",
home: Firstscreen(),
);
}
}
class Firstscreen extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("hello"),),
body: Center(
child: RaisedButton(
child: Text("下一页"),
color: Colors.lightBlue,
shape: StadiumBorder(),
onPressed: (){Navigator.push(context, MaterialPageRoute(
builder: (context)=>SecondScreen()
));},
),
)
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("data"),),
body: Center(
child: RaisedButton(child: Text("返回"),onPressed:(){
Navigator.push(context, MaterialPageRoute(
builder: (context)=>Firstscreen()
));
}),
),
);
}
}
十五 带参数传递的导航
import 'package:flutter/material.dart';
class Product {
final String title;
final String description;
Product(this.title,this.description);
}
void main() {
runApp(MyApp(products: List.generate(50,(i)=>Product("商品$i","这是一个商品详情,编号为$i")),));
}
class MyApp extends StatelessWidget {
final List<Product> products;
const MyApp({Key key,@required this.products}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "test1",
home: ProductList(
products:List.generate(products.length, (i)=>products[i])),
);
}
}
class ProductList extends StatelessWidget {
final List<Product> products;
const ProductList({Key key,@required this.products}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("products"),),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(products[index].title),
onTap: (){
Navigator.push(context, MaterialPageRoute(
builder: (context)=>SecondPage(product: products[index],)
));
},
);
},
),
);
}
}
class SecondPage extends StatelessWidget {
final Product product;
const SecondPage({Key key,@required this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("商品详情"),),
body: Text(product.description),
);
}
}
十六 异步请求和等待
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main(){
runApp(MaterialApp(
title: "页面跳转",
home:FirstPage(),
));
}
class FirstPage extends StatelessWidget {
const FirstPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("dataa"),),
body: Center(child:RouteBut()),
);
}
}
class RouteBut extends StatelessWidget {
const RouteBut({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return RaisedButton(
shape: StadiumBorder(),
onPressed: (){
_navi_in(context);
},
color: Colors.lightBlue,
child: Text("进入"),
);
}
_navi_in(BuildContext context) async{
final result=await Navigator.push(context,
MaterialPageRoute(
builder: (contex)=>SecondPage()
)
);
Scaffold.of(context).showSnackBar(SnackBar(content: Text(result),));
}
}
class SecondPage extends StatelessWidget {
const SecondPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(title: Text("设置返回数据"),),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text("返回数据1"),
onPressed: (){
Navigator.pop(context,"数据1");
},
),
RaisedButton(
child: Text("返回数据2"),
onPressed: (){
Navigator.pop(context,"数据2");
},
),
],
),
),
),
);
}
}
十七 加载静态资源
在项目里创建一个资源文件夹,放入资源
![v2-78a3c88162fdebd29ca8fb7dd362aa42_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/d77fe6b408e9fd7aa935ec5ae75a766b.png)
找到pubspec.yaml文件并打开
![v2-0012740bacd383badbbf9ef7a7c09903_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/aa1358bf5ad69965fcceedb23a633260.png)
注册资源:
![v2-a8aa402fcf47041e0c401e38a85acbd3_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/34a6bdbf81972921c25ca2ec4e414fd0.png)
注册后就可以引用了
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main()=>runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "myAPP",
home: Scaffold(
appBar: AppBar(title: Text("daaata"),),
body:Container(
child: Image.asset("images/test1.jpg"),
)
),
);
}
}
十八 Expanded //拓展组件
Expanded 组件可以让 Row、Column、Flex等子组件在其主轴方向上展开并填充可用空间。类似 Android 中的 widget 属性的用法
![v2-f35330735ab327b528e8655912b39342_b.png](https://i-blog.csdnimg.cn/blog_migrate/751e5a272733fb417b837e9e84e95a2f.png)
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APP
class MyApp extends StatelessWidget {
//app继承于StatelessWidget组件对象
@override //重构build方法
Widget build(BuildContext context) {
//组件的build的方法返回一个组件 参数是其上下文文件
final mytitle = "listview";
return MaterialApp(
//返回方法 返回组件
title: mytitle, //APP的title
home: Scaffold(
//APP的主体,其类型是一个脚手架Scaffold
appBar: AppBar(
//脚手架第一个组成是appbar
title: Text(mytitle), //appbar的title
),
body: Row(
children: <Widget>[
Image.network(
"https://i0.hdslb.com/bfs/bangumi/b919ca54abfa2aaed952f197da67211118944923.jpg@144w_144h.webp",
width: 50,
),
Text("这是一个非常非常非常非常长的句子!!!长到这个ROW放不下了!!!"),
Icon(Icons.sentiment_satisfied),
],
)),
);
}
}
![v2-3db9ce6547b68128d8fdbf1564c3fab8_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/acc322354a7e43f60f7cd309873d7281.jpeg)
如果用上expanded组件则:
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APP
class MyApp extends StatelessWidget {
//app继承于StatelessWidget组件对象
@override //重构build方法
Widget build(BuildContext context) {
//组件的build的方法返回一个组件 参数是其上下文文件
final mytitle = "listview";
return MaterialApp(
//返回方法 返回组件
title: mytitle, //APP的title
home: Scaffold(
//APP的主体,其类型是一个脚手架Scaffold
appBar: AppBar(
//脚手架第一个组成是appbar
title: Text(mytitle), //appbar的title
),
body: Row(
children: <Widget>[
Image.network(
"https://i0.hdslb.com/bfs/bangumi/b919ca54abfa2aaed952f197da67211118944923.jpg@144w_144h.webp",
width: 50,
),
Expanded(child: Text("这是一个非常非常非常非常长的句子!!!长到这个ROW放不下了!!!所以expanded组件就自动修改了一下文本样式,终于让ROW能显示了!!!"),),
Icon(Icons.sentiment_satisfied),
],
)),
);
}
}
![v2-b15319e41fd549fcbf6bc0fee675337b_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/36b3916e3f24abe840a2138cf6519495.png)
第四部分 打包与发布
Android打包(VScode)
一 配置APP图标
图标目录: /android/app/src/main/res/
进入之后你会看到很多mipmap-为前缀命名的文件夹,后边的是像素密度,可以看出图标的分辨率。
- mdpi (中) ~160dpi
- hdpi (高) ~240dip
- xhdpi (超高) ~320dip
- xxhdpi (超超高) ~480dip
- xxxhdpi (超超超高) ~640dip
将对应像素密度的图片放入对应的文件夹中,图片记得用png格式,记得名字要统一,才能一次性进行配置。
二 配置AndroidManifest.xml
这个文件主要用来配置APP的名称、图标和系统权限,所在的目录在:/android/app/src/main/AndroidManifest.xml
android:label="flutter_app" //配置APP的名称,支持中文
android:icon="@mipmap/ic_launcher" //APP图标的文件名称
三 生成keystore
keytool -genkey -v -keystore e:/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
![v2-149aabe38cacd093d1d28d6719ddfeeb_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/16d5790b9df2a51d5693f649f82257cc.jpeg)
![v2-18c240e29d830ac4f56242c5787db997_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/41adc9dc08fb218c85eaf6c1ecc7d760.png)
在安卓根目录建立key属性文件,并配置
storePassword=<password from previous step> //输入上一步创建KEY时输入的 密钥库 密码
keyPassword=<password from previous step> //输入上一步创建KEY时输入的 密钥 密码
keyAlias=key
storeFile=<E:/key.jks> //key.jks的存放路径
![v2-c6efbdc9ff168ba0aa939e01287cffca_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e55d59dab68f3d93bc365e83242b3108.jpeg)
四 配置android\app\build.gradle
在android{}上面添加如下代码:
def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
![v2-feb7cd2c5981d38dce30434abb5f555a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/db190fff355c211072b2268570ad3c47.png)
把下面内容替换
![v2-463958bee3009ca319630e53c2d39eff_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/ffbdcb3620cf7f54a640f5d22f4765fd.png)
替换成:
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
五 生成APK
运行命令:
flutter build apk