flutter框架一文通(一)
第一部分 vscode终端操作快捷键 第二部分 hello world程序 第三部分 常用组件
附:
flutter中文文档https://flutterchina.club/docs/
书籍:flutter实战 https://book.flutterchina.club/
flutter自动代码生成器 https://ui.flutterdart.cn/
第一部分 vscode终端操作快捷键:
运行模拟器:flutter run
更新页面:R
显示网格:P
android/IOS模式切换:O
关闭终端:Q
热更新方法:用debug,按照VS的提示配置即可,配置完成后 如下
image
第二部分. 框架简介及hello world
一、总体架构
1、总体架构
image
其中engine部分 :
-
skia 图形UI框架
-
dart 虚拟机dartVM
-
text 渲染纹理
其中Framework部分:
-
foundation:功能接口
-
animation: 动画
-
painting:图像
-
gestures:触控
-
rendering:渲染
-
widgets:组件
-
meterial:googleUI风格
-
cupertino:IOSUI风格
2、GPU渲染
image
3.状态控制
image
4.Flutter理论基础知识
二、写一个hello world程序
主程序在main.dart里
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件return MaterialApp( //返回方法 返回组件title: "welcome", //APP的titlehome: Scaffold( //APP的主体,其类型是一个脚手架ScaffoldappBar: AppBar( //脚手架第一个组成是appbartitle: Text("welcome to big bear's flutter!!!"), //appbar的title),body: Center( //脚手架的第二个组成是body 给body一个center组件做内容child: Text("hello 熊爸haha!"), //center里有一个子组件是 Text("???")),),);}
}
image
第三部分 常用静态组件
statelesswidget 无状态变化的组件
statefullwidget 有状态变化的组件
一、文字组件 Text("")
image
1.textAlign (文本对齐)
Text的子属性,可传入TextAlign类对象,比如:
TextAlign.center 居中
TextAlign.left 左对齐
TextAlign.right 右对齐
TextAlign.start 和文字开始对齐
TextAlign.end 和文字结束对齐
image
2. maxLines (最大显示行数)
Text的子属性,可传入数值
Text("hello 熊爸haha!锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。",textAlign: TextAlign.end,maxLines: 1,)
3. overflow 溢出处理
Text的子属性,可传入TextOverflow类对象
\begin{array}[a] {|a|ca|} \hline 对象 & 对象名称\ \hline TextOverflow.clip & 溢出裁剪 \ \hline TextOverflow.ellipsis & 溢出显示... \ \hline TextOverflow.fade &最后一行上下渐变 \ \hline \end{array}\
image
4. style 文字样式
Text的子属性,可传入TextStyle类对象
TextStyle类对象:
image
image
image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件return MaterialApp( //返回方法 返回组件title: "welcome", //APP的titlehome: Scaffold( //APP的主体,其类型是一个脚手架ScaffoldappBar: AppBar( //脚手架第一个组成是appbartitle: 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("???")),),);}
}
image
二、container组件 container() 容器
container() 相当于HTML里的div
image
image
image
image
image
image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件return MaterialApp( //返回方法 返回组件title: "welcome", //APP的titlehome: Scaffold( //APP的主体,其类型是一个脚手架ScaffoldappBar: AppBar( //脚手架第一个组成是appbartitle: 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("???")),),);}
}
image
三. image组件
image
image
image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件return MaterialApp( //返回方法 返回组件title: "welcome", //APP的titlehome: Scaffold( //APP的主体,其类型是一个脚手架ScaffoldappBar: AppBar( //脚手架第一个组成是appbartitle: 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,)), ),),);}
}
四. Align组件 //对齐组件
image
image
五. Scaffold组件 //(脚手架)
脚手架是flutter页面框架结构中最重要的一环,他是页面的框架骨骼基础
image
六. AppBar组件 //APP导航条
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(leading: Icon(Icons.home),title: Text("AppBar示例"),centerTitle: true,backgroundColor: Colors.deepPurpleAccent,actions: [IconButton(icon: Icon(Icons.print), tooltip: 'print', onPressed: () {}),IconButton(icon: Icon(Icons.plus_one), tooltip: 'more', onPressed: () {}),IconButton(icon: Icon(Icons.share), tooltip: 'share', onPressed: () {}),PopupMenuButton(itemBuilder: (context)=>>[PopupMenuItem(value: "share",child: Text("分享到朋友圈"),),PopupMenuItem(value: "quit",child: Text("退出"),)])],),body: Container(),),);}
}
image
image
七. FloatingActionButton //悬浮按钮组件
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("data"),),floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,floatingActionButton: FloatingActionButton(tooltip: "小贴士,解释按键后会发生什么",foregroundColor: Colors.black87,backgroundColor: Colors.amberAccent,hoverColor: Colors.deepPurple,focusColor: Colors.deepPurpleAccent,splashColor: Colors.greenAccent,highlightElevation: 5,hoverElevation: 15,elevation: 5,focusElevation: 10,autofocus: true,mini: true,child: Icon(Icons.add),onPressed: () {},),body: Container(),),);}
}
image
八. BottomAppBar组件 //底部导航条
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("data"),),floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,floatingActionButton: FloatingActionButton(child: Icon(Icons.add),onPressed: (){},),bottomNavigationBar: BottomAppBar(notchMargin: 10.0,color: Colors.amber, elevation: 10,child: Row(mainAxisSize: MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [IconButton(icon: Icon(Icons.search), onPressed: (){}),IconButton(icon: Icon(Icons.menu), onPressed: (){}),], ),),body: Container(),),);}
}
image
九. ButtonBar //按钮条组件
image
image
image
十. NestedScrollView //可嵌套的滚动视图结构
image
image
十一. SliverAppBar //可扩展折叠的滚动工具栏
SliverAppBar 必须作为NestedScrollView 的子项才有用!!!!
image
十一. FlexibleSpaceBar组件 //可折叠空间组件
FlexibleSpaceBar必须作为SliverAppBar的子项才有用!!!!
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("data"),),body: NestedScrollView(headerSliverBuilder: (context, beScrolled) {return [(centerTitle: true,expandedHeight: 200,floating: false,pinned: true,flexibleSpace: FlexibleSpaceBar(background: Image.network("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=793051438,2878586275&fm=11&gp=0.jpg",fit: BoxFit.cover,),title: Text("可折叠组件"),),)];},body: Center()),),);}
}
image
十二. listView组件 列表布局
ListView的children是组件类型,所以可以随便添加任意组件
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main() => runApp(MyApp()); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget{ //app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context){ //组件的build的方法返回一个组件 参数是其上下文文件return MaterialApp( //返回方法 返回组件title: "welcome", //APP的titlehome: Scaffold( //APP的主体,其类型是一个脚手架ScaffoldappBar: AppBar( //脚手架第一个组成是appbartitle: Text("welcome to big bear's flutter!!!"), //appbar的title),body: Center(child: Container(height: 200,color: Colors.pinkAccent,child: MyList001(),),)),);}
}
class MyList001 extends StatelessWidget{@overrideWidget build(BuildContext context) {return ListView(scrollDirection: Axis.horizontal,children: [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.generate(15,(i)=>"Item $i") //在myapp类里创建了一个属性叫items,它里面有一个列表//里面的(i)=>"Item $i"是自动生成列表的项,就像python 列表中可以写lambda表达式一样
));class MyApp extends StatelessWidget{ final List 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]}"), //通过重构函数,我们将外部的信息传入了动态列表中);},)),);}
}
十三. 网格列表布局
image
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{@overrideWidget build(BuildContext context) {return GridView.count(padding: EdgeInsets.all(5.0),crossAxisSpacing:5,crossAxisCount: 3,mainAxisSpacing: 5,childAspectRatio: 0.7,children: [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,),],);}
}
按拓展性构建动态网格
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IOvoid main() => runApp(MaterialApp(title: "组件",home: MyApp(),)); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget {List _buildList(int count) {return List.generate(count,(int index) => Container(child: Image.asset('images/${index + 1}.jpg')),);}//app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context) {//组件的build的方法返回一个组件 参数是其上下文文件return Scaffold(appBar: AppBar(title: Text("data"),),body: GridView.extent(maxCrossAxisExtent: 150.0,padding: EdgeInsets.all(4.0),mainAxisSpacing: 4.0,crossAxisSpacing: 4.0,children: _buildList(9),),);}
}
image
十四. 按钮组件
image
十五. 水平布局
Row组件水平布局,搭配Expanded组件 可实现灵活的水平布局
对Row来说 主轴是水平方向
image
image
image
image
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: [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"),),)],),),);}
}
十六. 垂直布局
image
对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: [Text("熊爸"),Expanded(child: Text("锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。"),),Text("data"),],),),);}
}
十七. Stack组件、Position组件(层叠布局 )
两层堆叠用Stack组件
多层堆叠用Position组件
image
image
image
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: [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),),)],),),);}
}
image
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: [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")),],),),);}
}
十八. 圆盘组件
image
十九. 瓦片组件
image
二十. 卡片布局
image
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: [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),),],),),),);}
}
例2:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("FlatButton")),body: Column(children: [Card(color: Colors.red[100],margin: EdgeInsets.all(10),child: Column(mainAxisSize: MainAxisSize.min,children: [ListTile(leading: Icon(Icons.shopping_basket),title: Text("一加手机 OnePlus7pro",style: TextStyle(fontSize: 25),),subtitle: Text("8+256G"),contentPadding: EdgeInsets.all(10),trailing: Text("¥3999",style:TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),),ButtonBar(children: [FlatButton.icon(textColor: Colors.deepPurple,onPressed: () {},icon: Icon(Icons.shopping_cart),label: Text("购买")),FlatButton.icon(textColor: Colors.redAccent,onPressed: () {},icon: Icon(Icons.favorite),label: Text("收藏")),],)],),),Card(color: Colors.orange,margin: EdgeInsets.all(10),child: Column(mainAxisSize: MainAxisSize.min,children: [ListTile(leading: Icon(Icons.shopping_basket),title: Text("小米手机 CC9",style: TextStyle(fontSize: 25),),subtitle: Text("8+256G"),contentPadding: EdgeInsets.all(10),trailing: Text("¥1999",style:TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),),ButtonBar(children: [FlatButton.icon(textColor: Colors.deepPurple,onPressed: () {},icon: Icon(Icons.shopping_cart),label: Text("购买")),FlatButton.icon(textColor: Colors.redAccent,onPressed: () {},icon: Icon(Icons.favorite),label: Text("收藏")),],)],),),Card(color: Colors.green,margin: EdgeInsets.all(10),child: Column(mainAxisSize: MainAxisSize.min,children: [ListTile(leading: Icon(Icons.shopping_basket),title: Text("OPPO手机 FindX2",style: TextStyle(fontSize: 25),),subtitle: Text("8+256G"),contentPadding: EdgeInsets.all(10),trailing: Text("¥3599",style:TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),),ButtonBar(children: [FlatButton.icon(textColor: Colors.deepPurple,onPressed: () {},icon: Icon(Icons.shopping_cart),label: Text("购买")),FlatButton.icon(textColor: Colors.redAccent,onPressed: () {},icon: Icon(Icons.favorite),label: Text("收藏")),],)],),),Card(color: Colors.blueGrey,margin: EdgeInsets.all(10),child: Column(mainAxisSize: MainAxisSize.min,children: [ListTile(leading: Icon(Icons.shopping_basket),title: Text("华为手机 Mate30",style: TextStyle(fontSize: 25),),subtitle: Text("8+256G"),contentPadding: EdgeInsets.all(10),trailing: Text("¥3799",style:TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),),ButtonBar(children: [FlatButton.icon(textColor: Colors.deepPurple,onPressed: () {},icon: Icon(Icons.shopping_cart),label: Text("购买")),FlatButton.icon(textColor: Colors.redAccent,onPressed: () {},icon: Icon(Icons.favorite),label: Text("收藏")),],)],),),],),),);}
}
image
二十一. 分割线组件
Divider()
二十二. 导航
Navigator.push(context, route); //压栈,压入下一页
Navigator.pop(context); //弹栈,弹出一层
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IOvoid main() => runApp(MaterialApp(title: "组件",home: MyApp(),)); //main函数只有一句话:运行APPclass FirstPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("第一页"),),body: Center(child: RaisedButton(child: Text("进入第二页"),onPressed: () {Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));},),),);}
}class SecondPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("第二页"),),body: Column(children: [RaisedButton(child: Text("返回"),onPressed: () {Navigator.pop(context);},),RaisedButton(child: Text("进入第三页"),onPressed: (){Navigator.push(context, MaterialPageRoute(builder: (context)=>ThirdPage()));},),],),);}
}class ThirdPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("第三页"),),body: Center(child: RaisedButton(child: Text("返回"),onPressed: () {Navigator.pop(context);},),),);}
}class MyApp extends StatelessWidget {//app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context) {//组件的build的方法返回一个组件 参数是其上下文文件return FirstPage();}
}
image
二十三. 带参数传递的导航
Navigator.push(context, MaterialPageRoute(builder: ( (context)=>SecPage(product: products[index],) )));
其实就是在构造函数中传递.
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 products;const MyApp({Key key,@required this.products}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(title: "test1",home: ProductList(products:List.generate(products.length, (i)=>products[i])),);}
}
class ProductList extends StatelessWidget {final List products;const ProductList({Key key,@required this.products}) : super(key: key);@overrideWidget 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);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("商品详情"),),body: Text(product.description),);}
}
例二:页面跳转发送数据
import 'package:flutter/material.dart';class Product {final String title;final String description;Product(this.title, this.description);
}void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "页面间数据传递",home: ProductList(products: List.generate(20, (i) => "$i"),),);}
}class ProductList extends StatelessWidget {final List products;ProductList({Key key, @required this.products}) : super(key: key);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("商品汇总页")),body: ListView.builder(itemCount: products.length,itemBuilder: (context, index) {return ListTile(title: Text("这是商品:$index"),onTap: () {Navigator.push(context,MaterialPageRoute(builder: ((context) => SecPage(product: Product("$index","这件$index 号商品是我们村的爆款哦!"),))));},);},));}
}class SecPage extends StatelessWidget {final Product product;SecPage({Key key, @required this.product}) : super(key: key);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("$product 的商品详情")),body: Center(child: Column(children: [Text("商品显示在这里,商品编号:${product.title},\n商品描述:${product.description}.\n它$product 非常诱人!!\n您还在犹豫个啥???😡",style: TextStyle(fontSize: 20),),RaisedButton(child: Text("返回"),onPressed: () {Navigator.pop(context);},),],),),);}
}
image
例三:页面跳转返回数据
二十四. 异步请求和等待
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);@overrideWidget 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);@overrideWidget 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);@overrideWidget build(BuildContext context) {return Container(child: Scaffold(appBar: AppBar(title: Text("设置返回数据"),),body: Center(child: Column(children: [RaisedButton(child: Text("返回数据1"),onPressed: (){Navigator.pop(context,"数据1");},),RaisedButton(child: Text("返回数据2"),onPressed: (){Navigator.pop(context,"数据2");},),],),),),);}
}
二十五. 加载静态资源
在项目里创建一个资源文件夹,放入资源
image
找到pubspec.yaml文件并打开
image
注册资源:
image
注册后就可以引用了
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IO
void main()=>runApp(MyApp());class MyApp extends StatelessWidget {const MyApp({Key key}) : super(key: key);@overrideWidget 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 属性的用法
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IOvoid main() => runApp(MyApp()); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget {//app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context) {//组件的build的方法返回一个组件 参数是其上下文文件final mytitle = "listview";return MaterialApp(//返回方法 返回组件title: mytitle, //APP的titlehome: Scaffold(//APP的主体,其类型是一个脚手架ScaffoldappBar: AppBar(//脚手架第一个组成是appbartitle: Text(mytitle), //appbar的title),body: Row(children: [Image.network("https://i0.hdslb.com/bfs/bangumi/b919ca54abfa2aaed952f197da67211118944923.jpg@144w_144h.webp",width: 50,),Text("这是一个非常非常非常非常长的句子!!!长到这个ROW放不下了!!!"),Icon(Icons.sentiment_satisfied),],)),);}
}
image
如果用上expanded组件则:
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IOvoid main() => runApp(MyApp()); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget {//app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context) {//组件的build的方法返回一个组件 参数是其上下文文件final mytitle = "listview";return MaterialApp(//返回方法 返回组件title: mytitle, //APP的titlehome: Scaffold(//APP的主体,其类型是一个脚手架ScaffoldappBar: AppBar(//脚手架第一个组成是appbartitle: Text(mytitle), //appbar的title),body: Row(children: [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),],)),);}
}
image
二十七. sizebox盒模型
image
二十八. GestureDetector组件(手势监听)
image
image
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IOvoid main() => runApp(MaterialApp(title: "组件",home: MyApp(),)); //main函数只有一句话:运行APPclass Mybutton extends StatelessWidget{@overrideWidget build(BuildContext context) {return GestureDetector(onTap: (){final mysnak=SnackBar(content: Text("触发ontap,冒出提示框!!"));Scaffold.of(context).showSnackBar(mysnak);},child: Container(padding: EdgeInsets.all(12.0),decoration: BoxDecoration(color: Theme.of(context).buttonColor,borderRadius: BorderRadius.circular(10.0), ), child: Text("点一下"),),);}
}
class MyApp extends StatelessWidget {//app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context) {//组件的build的方法返回一个组件 参数是其上下文文件return Scaffold(appBar: AppBar(title: Text("data"),),body: Center(child:Mybutton()),);}
}
image
二十九. Dismissible组件(滑动删除)
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IOvoid main() => runApp(MaterialApp(title: "组件",home: MyApp(),)); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget {List items = List.generate(30, (i) => "item${i + 1}");//app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context) {//组件的build的方法返回一个组件 参数是其上下文文件return Scaffold(appBar: AppBar(title: Text("data"),),body: ListView.builder(itemCount: items.length,itemBuilder: (context, index) {return Dismissible(key: Key(items[index]),onDismissed: (derction) {items.removeAt(index);Scaffold.of(context).showSnackBar(SnackBar(content: Text("data:$derction")));},child: ListTile(title: Text("列表${items[index]}"),),);},),);}
}
image
三十. SnackBar
image
Scaffold.of(context).showSnackBar(SnackBar(content: Text("data:$derction")));
例2:
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("data"),),body: Center(child: MyBut1(),)));}
}class MyBut1 extends StatelessWidget {final mySnak1 = SnackBar(content: Row(children: [Icon(Icons.cake),Text("感谢点击!!"),],),backgroundColor: Colors.deepPurpleAccent,//持续时间duration: Duration(milliseconds: 1500),//反馈动作action: SnackBarAction(label: "OK", textColor: Colors.greenAccent, onPressed: () {}),);@overrideWidget build(BuildContext context) {return RaisedButton(child: Text("点击出现snackBar"),onPressed: () {Scaffold.of(context).showSnackBar(mySnak1);},);}
}
image
三十一. 自定义字体
1.新建字体文件夹font 并放入字体文件
image
2.在pubspec.yaml文件中注册字体.
image
3.在程序中引用
import 'package:flutter/material.dart'; // 一个UI库 www.Material.IOvoid main() => runApp(MaterialApp(title: "组件",home: MyApp(),)); //main函数只有一句话:运行APPclass MyApp extends StatelessWidget {List items = List.generate(30, (i) => "item${i + 1}");//app继承于StatelessWidget组件对象@override //重构build方法Widget build(BuildContext context) {//组件的build的方法返回一个组件 参数是其上下文文件return Scaffold(appBar: AppBar(title: Text("data"),),body: Center(child: Text("自定d义字体1data!!?!!@#%@#abasdasdaxkl123454563😀",style: TextStyle(fontSize: 25,fontFamily: "xkzzt",),),),);}
}
三十二. hero组件 //页面过度动画
image
注意:要过渡的两个页面应该设置同样的tag
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "test",home: FirstPage(),);}
}class FirstPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("第一页"),),body: GestureDetector(child: Hero(tag: "pic1",child: Icon(Icons.picture_in_picture),),onTap: () {Navigator.push(context, MaterialPageRoute(builder: (contex) => SecPage()));},),);}
}class SecPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("第二页")),body: Center(child: GestureDetector(child: Hero(tag: "pic1",child: Image.network("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1581017576843&di=e5876e0581a47faa82797803e4949794&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20180910%2Ff96bbc903e094492a571515d0e417bf3.jpeg"),),onTap: () {Navigator.pop(context);},),),);}
}
image
三十三. ConstrainedBox //可伸缩盒子
伸缩盒子给子组件限定了一个最大和最小空间,子组件不得超过此空间.
image
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("ConstrainedBox")),body: Container(height: 500,child: ConstrainedBox(constraints: BoxConstraints(maxWidth:300, minHeight: 200,maxHeight: 500,minWidth: 200,),child: Container(width: 0,height: 600, color: Colors.redAccent,), ),),));}
}
三十四. DecoratedBox //带装饰的盒子
image
image
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("bottomNavigatorBar")),body: Center(child: Container(width: 350,height: 600,child: DecoratedBox(position: DecorationPosition.foreground,//决定装饰器位置,会不会遮挡child里的组件decoration: BoxDecoration(color: Colors.teal,image: DecorationImage(image: NetworkImage('http://a1.att.hudong.com/05/00/01300000194285122188000535877.jpg'),),borderRadius: BorderRadius.circular(20),backgroundBlendMode: BlendMode.colorBurn,border: Border.all(width: 6,color: Colors.black38,),//shape: BoxShape.rectangle),child: Text("可爱可爱小猫咪",style: TextStyle(fontSize: 25),),),),),));}
}
image
三十五. FittedBox //自适应填充盒模型
此盒子允许他的子组件有自适应性
image
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("FittedBox")),body: Column(children: [Container(width: 200,height: 100,color: Colors.greenAccent,child: FittedBox(fit: BoxFit.fill,alignment: Alignment.center,child: Text("使用fill模式自适应"),),)],),),);}
}
image
三十六. OverflowBox //允许溢出的盒模型
此盒子允许他的子组件溢出
image
image
三十七. RotatedBox //允许旋转盒模型
此盒子允许他的子组件旋转,会顺时针旋转 quarterTurns × 90°
image
image
注意data的方向
三十八. SizedBox //限定大小的盒模型
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("RotatedBox")),body: SizedBox(width: 200,height: 200,child: Container(width: 400,height: 100,color: Colors.blue,)),),);}
}
image
子组件设置了宽高,但不管用了
三十九. FlatButton //扁平按钮组件
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("FlatButton")),body: Center(child: Column(children: [FlatButton(child: Text("data"),colorBrightness: Brightness.dark,onHighlightChanged: (n) {},onPressed: () {},onLongPress: () {},color: Colors.pinkAccent,),FlatButton.icon(color: Colors.amberAccent,onPressed: () {},icon: Icon(Icons.history),label: Text("null")),],),),),);}
}
image
四十. IconButton //图标按钮组件
image
四十一 OutlineButton //外边线按钮组件
image
四十二. RawMaterialButton //原始按钮组件
image
第四部分 常用动态组件
一. tabbar组件 //选项卡
选项卡是一个动态组件,动态组件创建如下:
image
创建步骤:
1.在appbar中加一个tabbar
2.在body中加一个tabbarview
3.制作一个控制器_tabController来关联上面的二者
4.重写initState() dispose() 用来实现上述控制器
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST", home: Demo());}
}class Demo extends StatefulWidget {@override_DemoState createState() => _DemoState();//重写创建状态
}class _DemoState extends State with SingleTickerProviderStateMixin {//必须加SingleTickerProviderStateMixinScrollController _scrollController; //类内声明了一个ScrollController组件,名叫_scrollControllerTabController _tabController;//类内声明了一个TabController组件,名叫_tabController@overridevoid initState() { //重写初始化状态函数super.initState(); //必须先继承父类_scrollController = ScrollController(); //初始化时创建一个ScrollController,赋值给_scrollController_tabController = TabController(length: 6, vsync: this);//初始化时创建一个TabController,赋值给_tabController//length必须与选项卡数量对应 }@overridevoid dispose() { //重写释放函数_scrollController.dispose(); //注销_scrollController组件_tabController.dispose();//注销_tabController组件super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(leading: Icon(Icons.home),title: Text("tabBar"),bottom: TabBar( //在APPBAR的底部加一个tabbarcontroller: _tabController, //控制器为_tabControllertabs: [ //里面的TabTab(text: '语文',icon: Icon(Icons.font_download),),Tab(text: '数学',icon: Icon(Icons.format_list_numbered),),Tab(text: '英语',icon: Icon(Icons.nature),),Tab(text: '历史',icon: Icon(Icons.history),),Tab(text: '地理',icon: Icon(Icons.map),),Tab(text: '生物',icon: Icon(Icons.book),),],),),body: TabBarView( //在body里加一个TabBarViewcontroller: _tabController, //也用_tabController作为控制器,这样就能和tabbar对应起来children: [ //子元素个数应该和tabbar对应起来Text("语文"),Text("数学"),Text("英语"),Text("历史"),Text("地理"),Text("生物"),],),);}
}
image
二. 底部导航栏
image
image
image
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("bottomNavigatorBar")),body: Container(height: 500,),bottomNavigationBar: Demo(),));}
}class Demo extends StatefulWidget {@override_DemoState createState() => _DemoState();
}class _DemoState extends State {int _currentIndex = 1;void _onItemTapped(int index) {setState(() {_currentIndex = index;});}@overrideWidget build(BuildContext context) {return BottomNavigationBar(onTap: _onItemTapped,type: BottomNavigationBarType.fixed,currentIndex: _currentIndex,items: [BottomNavigationBarItem(title: Text("book"),icon: Icon(Icons.book),),BottomNavigationBarItem(title: Text("shop"),icon: Icon(Icons.shop),),BottomNavigationBarItem(title: Text("music"),icon: Icon(Icons.queue_music),),],);}
}
image
三. 下拉按钮组件
image
image
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "TEST",home: Scaffold(appBar: AppBar(title: Text("DropdownButDemo")),body: Center(child: DropdownButDemo(),),),);}
}class DropdownButDemo extends StatefulWidget {@override_DropdownButDemoState createState() => _DropdownButDemoState();
}class _DropdownButDemoState extends State with SingleTickerProviderStateMixin {int _cureentValue=1;List dropItemsList(){final List mitems=List();final DropdownMenuItem item1 =DropdownMenuItem(child: Text("book"),value: 1);final DropdownMenuItem item2 =DropdownMenuItem(child: Text("shop"),value: 2);final DropdownMenuItem item3 =DropdownMenuItem(child: Text("cake"),value: 3);final DropdownMenuItem item4 =DropdownMenuItem(child: Text("bank"),value: 4);mitems.add(item1);mitems.add(item2);mitems.add(item3);mitems.add(item4);return mitems;}@overrideWidget build(BuildContext context) {return DropdownButton(value: _cureentValue,items: dropItemsList(),//下拉列表hint: Text("请下拉"),//提示文本iconSize: 48,//图标大小elevation: 10,//阴影isExpanded: true,//继承父容器的大小focusColor: Colors.redAccent, //获得焦点的颜色iconEnabledColor: Colors.amber,//按钮可用时的颜色iconDisabledColor: Colors.grey,//按钮不可用时的颜色icon: Icon(Icons.keyboard_arrow_down),style: TextStyle(fontSize: 30,color: Colors.black54,),//字体样式isDense:true,itemHeight:80,autofocus: true,onChanged: (T){setState((){_cureentValue=T;});}, );}
}
image
第五部分 打包与发布
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
image
image
在安卓根目录建立key属性文件,并配置
storePassword= //输入上一步创建KEY时输入的 密钥库 密码
keyPassword= //输入上一步创建KEY时输入的 密钥 密码
keyAlias=key
storeFile= //key.jks的存放路径
image
四 配置android\app\build.gradle
在android{}上面添加如下代码:
def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
image
把下面内容替换
image
替换成:
signingConfigs {release {keyAlias keystoreProperties['keyAlias']keyPassword keystoreProperties['keyPassword']storeFile file(keystoreProperties['storeFile'])storePassword keystoreProperties['storePassword']}
}
buildTypes {release {signingConfig signingConfigs.release}
}
五 生成APK
运行命令:
flutter build apk
十九 Android打包(AS)
作者:熊爸天下_56c7
链接:https://www.jianshu.com/p/2f33a5f9f546
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
