flutter 学习文档
Flutter 官方文档https://flutter.dev
Flutter 中文网 https://flutterchina.club
Material设计规范 http://material.io/
Flutter 中文网手势文档地址:https://flutterchina.club/gestures/
Flutter 手势文档原文档地址:flutter.io/gestures
组件 控件
Flutter TEXT文档地址:https://docs.flutter.io/flutter/widgets/Text-class.html
Flutter img控件文档地址:https://docs.flutter.io/flutter/widgets/Image-class.html
Flutter Container(容器)文档地址:https://docs.flutter.io/flutter/widgets/Container-class.html
Flutter List View 文档地址:https://docs.flutter.io/flutter/widgets/ListView-class.html
Flutter 水平列表文档地址:https://docs.flutter.io/flutter/widgets/ListView-class.html
Flutter长列表文档地址:https://docs.flutter.io/flutter/widgets/ListView-class.html
Flutter GridView(网格列表)文档地址:
https://docs.flutter.io/flutter/widgets/GridView-class.html
Flutter Row (包装控件)文档地址:https://docs.flutter.io/flutter/widgets/Row-class.html
Flutter APP eg 文档:https://docs.flutter.io/flutter/material/AppBar-class.html
Flutter Scaffold 文档:https://docs.flutter.io/flutter/material/Scaffold-class.html
布局
水平布局:Flutter Row 文档地址:https://docs.flutter.io/flutter/widgets/Row-class.html
垂直布局:Flutter 文档地址:https://docs.flutter.io/flutter/widgets/Column-class.html
GridView布局Flutter GridView 文档地址:
https://docs.flutter.io/flutter/widgets/GridView-class.html
ListView布局: Flutter List View 文档地址:
https://docs.flutter.io/flutter/widgets/ListView-class.html
Contalner布局 : Flutter Container 文档地址:
https://docs.flutter.io/flutter/widgets/Container-class.html
Stack布局 ( 层 叠 ) Flutter Stack 文档:
https://docs.flutter.io/flutter/widgets/Stack-class.html
Card布局
层叠定位布局 Flutter Positioned 文档地址:
https://docs.flutter.io/flutter/widgets/Positioned-class.html
手势处理
按下手势
文档地址:https://docs.flutter.io/flutter/widgets/GestureDetector-class.html
滑动 删除手势
文档位置:https://docs.flutter.io/flutter/widgets/Dismissible-class.html
资源、图片处理
文档地址:https://flutter.dev/docs/development/ui/assets-and-images
学习地址:亢少军·老师 free https://edu.csdn.net/course/play/9268/207056
一、 Flutter 总体架构
1. Flutter 架构
解释
Engine 引擎
Skia 图形UI框架
Dart 虚拟机
Text 纹理 渲染,
Framework 框架
Foundation 接口层
Animation 动画
Painting 渲染
Gestures 触控
Rendering 渲染
Widget 组件
Material Google规范 Android 风格
Cupertino 猜测 apple 规范
2. Flutter GPU
3. Flutter 状态控制
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: 'Flutter Tutorial',
home: new TutorialHome(),
));
}
class TutorialHome 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('Example title'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
//body占屏幕的大部分
body: new Center(
child: MyButton(),
),
floatingActionButton: new FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: new Icon(Icons.add),
onPressed: null,
),
);
}
}
//自定义组件
class MyButton extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return GestureDetector(
onTap: (){
//按钮显示字
print('mybutton');
},
child: Container(
//按钮高度
height: 42.0,
//
padding: const EdgeInsets.all(16.0),
margin: const EdgeInsets.symmetric(horizontal: 8.0),
decoration: BoxDecoration(
//按钮圆角 值越大弧度越大
borderRadius: BorderRadius.circular(5.0),
color: Colors.lightBlue,
),
child: Center(
child: Text('Engage'),
),
),
);
}
}
三、 组件 控件 详解
1. TEXT组件
Flutter TEXT文档地址:https://docs.flutter.io/flutter/widgets/Text-class.html
Text(
//输出
‘Hello, $_name! How are you?’,
//显示位置 左中右
textAlign: TextAlign.center,
// 多行文本溢出显示省略号(…)
overflow: TextOverflow.ellipsis,
//样式
style: TextStyle(fontWeight: FontWeight.bold),
)
Text组件 demo
import 'package:flutter/material.dart';
class ContainerDemo extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text('文本控件'),
),
body: new Column(
children: <Widget>[
new Text(
'红色+黑色删除线+25号',
style: new TextStyle(
//字体颜色
color: const Color(0xfff00000),
//删除线
decoration: TextDecoration.lineThrough,
//线色
decorationColor: const Color(0xff000000),
fontSize: 25.0,
),
),
new Text(
'橙色+下划线+25号',
style: new TextStyle(
color: const Color(0xffff9900),
decoration: TextDecoration.underline,
fontSize: 25.0,
),
),
new Text(
'粉色+上划线 虚线+25号 + 倾斜',
style: new TextStyle(
color: const Color(0xffff9990),
decoration: TextDecoration.overline,
decorationStyle: TextDecorationStyle.dashed,
fontSize: 25.0,
fontStyle: FontStyle.italic,
),
),
new Text(
'粉色+上划线 虚线+25号 + 倾斜+加粗',
style: new TextStyle(
//字体颜色
color: const Color(0xffff9990),
//上划线
decoration: TextDecoration.overline,
//虚线
decorationStyle: TextDecorationStyle.dashed,
fontSize: 25.0,
//字体倾斜
fontStyle: FontStyle.italic,
//字体加粗
fontWeight: FontWeight.bold,
//字体间隔
letterSpacing: 6.0
),
),
],
),
);
}
}
void main(){
runApp(
new MaterialApp(
title: 'Text demo',
home: new ContainerDemo(),
)
);
}
result
2. 输入框 组件
Input Demo
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: "input",
home: new Scaffold(
appBar: new AppBar(
title: new Text("输入事件"),
),
body: new LogoApp(),
),
));
}
class LogoApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new LogoAppState();
}
}
class LogoAppState extends State<LogoApp> {
// material包下的类 可编辑文本控制器 text将被作为初始文本显示在TextField中
// final TextEditingController _controller = new TextEditingController(text: "duo_shine");
//text将被作为初始文本显示在TextField中
final TextEditingController _controller =
new TextEditingController.fromValue(new TextEditingValue(text: "duo_shine"));
@override
Widget build(BuildContext context) {
//通过Opacity的透明度值来控制 widget显示和隐藏 这比在树中删除和添加widget效率更高
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField(
controller: _controller,
decoration: new InputDecoration(
hintText: "用户名",
)),
new RaisedButton(
onPressed: () {
// _controller.clear(); 将值设置为空
showDialog(
context: context,
//_controller.text 用户正在编辑的当前字符串
child: new AlertDialog(
title: new Text("用户名"),
content: new Text(_controller.text),
));
},
child: new Text("登录"),
)
],
);
}
}
3. 图片控件
Flutter img控件文档地址:https://docs.flutter.io/flutter/widgets/Image-class.html
BoxFit: Cover 视频 平铺
Image Demo
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: 'Text demo',
home: new ImageDemo(),
));
}
class ImageDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
var src = "https://cdn.jsdelivr.net/gh/flutterchina/website@1.0/images/flutter-mark-square-100.png";
return new Center(
child: new Image.network(
src,
//数值越大,图片越小
//scale: 0.5,
fit: BoxFit.fitWidth,
),
);
}
}
result
4. 容器控件
Flutter Container 文档地址:https://docs.flutter.io/flutter/widgets/Container-class.html
margin 属性用于在一个声明中设置所有当前或者指定元素所有外边距的宽度,或者设置各边上外边距的宽度
padding 定义元素边框与元素内容之间的空间,简写属性在一个声明中设置所有内边距属性。设置所有当前或者指定元素内边距属性。该属性可以有1到4个值,上右下左
ContainerDemo
import 'package:flutter/material.dart';
void main(){
runApp(
new MaterialApp(
title: 'Text demo',
home: new ContainerDemo(),
)
);
}
class ContainerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
//final 不可修改的
// final title = "ListView Demo";
return new Center(
child: new Container(
width: 300.0,
height: 300.0,
decoration: new BoxDecoration(
//数值越大,颜色越深
color: Colors.lightBlueAccent[100],
border: new Border.all(
color: const Color(0xffff0000),
width: 8.0,
),
//加角的弧度,数值越大角越原
borderRadius: const BorderRadius.all(const Radius.circular(18.0))
),
//添加内容
child: new Text(
'hello',
textAlign: TextAlign.center,
),
),
);
}
}
result
6. 基础列表
Flutter List View 文档地址:https://docs.flutter.io/flutter/widgets/ListView-class.html
ListDemo
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//final 不可修改的
final title="ListView Demo";
return new MaterialApp(
title: '水平',
home: new Scaffold(
appBar: new AppBar(
title: new Text(title),
),
body: new ListView(
children: <Widget>[
//列表项
new ListTile(
leading: new Icon(Icons.alarm),
title: new Text('Alarm'),
),
new ListTile(
leading: new Icon(Icons.phone),
title: new Text('phone'),
),
new ListTile(
leading: new Icon(Icons.airplay),
title: new Text('airplay'),
),
new ListTile(
leading: new Icon(Icons.local_activity),
title: new Text('airplay'),
),
new ListTile(
leading: new Icon(Icons.add),
title: new Text('add'),
),
],
),
),
);
}
}
result
7. 水平列表
Flutter 水平列表文档地址:https://docs.flutter.io/flutter/widgets/ListView-class.html
Horizontal list Demo
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//final 不可修改的
final title = "Horizontal list Demo";
return new MaterialApp(
title: title,
home: new Scaffold(
appBar: new AppBar(
title: new Text(title),
),
body: new Container(
margin: new EdgeInsets.symmetric(vertical: 20.0),
height: 200.0,
child: new ListView(
//水平方向排列
scrollDirection: Axis.horizontal,
children: <Widget>[
new Container(
width: 160,
color: Colors.lightBlue,
child: new Container(
width: 50,
height: 50,
decoration: new BoxDecoration(
color: Colors.pink,
border: new Border.all(
color: const Color(0xff00ff00),
width: 2.0,
),
),
),
),
new Container(
width: 160,
color: Colors.lightGreen,
//row 水平排列
child: new Row(
children: <Widget>[
new Text('简介'),
new Text(
'吉萨',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 36.0,
)
),
new Icon(Icons.airplanemode_active)
],
),
),
new Container(
width: 160,
color: Colors.amber,
//垂直排列
child: new Column(
children: <Widget>[
new Text('简介'),
new Text(
'吉萨',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 36.0,
)
),
new Icon(Icons.airplanemode_active)
],
),
),
new Container(
width: 160,
color: Colors.deepPurple,
),
],
),
),
),
);
}
}
result
8. 长列表
文档地址:https://docs.flutter.io/flutter/widgets/ListView-class.html
多元素不同值
ListView.builder itenBuliter 相同元素 itemExtent 个数
长列表 demo
import 'package:flutter/material.dart';
void main() => runApp(new MyApp(
items: new List<String>.generate(1000, (i) => "Item $i"),
));
class MyApp extends StatelessWidget {
final List<String> items;
MyApp({Key key, @required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
//final 不可修改的
final title = "长列表 demo";
return new MaterialApp(
title: title,
home: new Scaffold(
appBar: new AppBar(
title: new Text(title),
),
body: new ListView.builder(
itemCount: items.length,
itemBuilder: (context,index){
return new ListTile(
leading: new Icon(Icons.access_alarms),
title: new Text('${items[index]}'),
);
},
)
),
);
}
}
result
9. 网格列表
Flutter GridView 文档地址:https://docs.flutter.io/flutter/widgets/GridView-class.html
多行多列
GridView demo
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//final 不可修改的
final title = "网格列表 demo";
return new MaterialApp(
title: title,
home: new Scaffold(
appBar: new AppBar(
title: new Text(title),
),
body: new GridView.count(
primary: false,
//外间隙
padding: const EdgeInsets.all(20.0),
//列间隙
crossAxisSpacing: 10.0,
//列数
crossAxisCount: 2,
//每格设定
children: <Widget>[
const Text('第一行第一列'),
const Text('第一行第二列'),
const Text('第二行第一列'),
const Text('第二行第一列'),
const Text('第一行第一列'),
const Text('第一行第一列'),
],
)
),
);
}
}
result
10. 包装控件
Flutter Row 文档地址:https://docs.flutter.io/flutter/widgets/Row-class.html
Row Demo
import 'package:flutter/material.dart';
void main() => runApp(
new MaterialApp(
title: '包装控件',
home: new LayoutDemo(),
));
class LayoutDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
Widget packedRow = new Row(
//小图标
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Icon(Icons.star,color: Colors.green[50],),
new Icon(Icons.star,color: Colors.green[100],),
new Icon(Icons.star,color: Colors.green[200],),
new Icon(Icons.star,color: Colors.green[300],),
new Icon(Icons.star,color: Colors.green[400],),
],
);
return new Scaffold(
appBar: new AppBar(
title: new Text('包装控件'),
),
body: packedRow,
);
}
}
result
11. App 滴滴出行 demo
手机页面布局
Action 按钮
Ledding 返回
Botton
Flutter APP eg 文档:https://docs.flutter.io/flutter/material/AppBar-class.html
Flutter Scaffold 文档:https://docs.flutter.io/flutter/material/Scaffold-class.html
DidiSample Demo 1
import 'package:flutter/material.dart';
class DidiSample extends StatefulWidget {
@override
_DidiSampleState createState() => _DidiSampleState();
}
class _DidiSampleState extends State<DidiSample> {
Choice _selectedChoice = choices[0];
void _select(Choice choice) {
setState(() {
_selectedChoice = choice;
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('滴滴出行'),
actions: <Widget>[
IconButton(
icon: Icon(choices[0].icon),
onPressed: () {
_select(choices[0]);
},
),
IconButton(
icon: Icon(choices[1].icon),
onPressed: () {
_select(choices[1]);
},
),
//将后面的变为缩略
PopupMenuButton<Choice>(
//选择后回调
onSelected: _select,
itemBuilder: (BuildContext context) {
//跳过
return choices
.skip(2)
.map<PopupMenuItem<Choice>>((Choice choice) {
return PopupMenuItem<Choice>(
value: choice,
child: Text(choice.title),
);
}).toList();
},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: ChoiceDidi(choice:_selectedChoice),
),
),
);
}
}
//定义
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
//出行方式
const List<Choice> choices = <Choice>[
Choice(title: '自行车', icon: Icons.directions_bike),
Choice(title: '自驾', icon: Icons.directions_car),
Choice(title: '乘船', icon: Icons.directions_boat),
Choice(title: '公交', icon: Icons.directions_bus),
Choice(title: '火车', icon: Icons.directions_railway),
Choice(title: '步行', icon: Icons.directions_walk),
Choice(title: '灰机', icon: Icons.airplanemode_active),
];
class ChoiceDidi extends StatelessWidget{
const ChoiceDidi({Key key,this.choice}):super(key : key);
final Choice choice;
@override
Widget build(BuildContext context) {
// TODO: implement build
//主题颜色
final TextStyle textStyle = Theme.of(context).textTheme.display1;
//包装
return Card(
color: Colors.white,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
//居中
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(choice.icon,size: 128.0,color: textStyle.color,),
Text(choice.title,style: textStyle,)
],
),
),
);
}
}
void main(){
runApp(DidiSample());
}
Demo1 result
Demo2
import 'package:flutter/material.dart';
class DidiSample extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
home: new DefaultTabController(
length: choices.length,
child: new Scaffold(
appBar: new AppBar(
title: const Text('滴滴出行'),
bottom: new TabBar(
tabs: choices.map((Choice choice) {
return new Tab(
text: choice.title,
icon: new Icon(choice.icon),
);
}).toList(),
//标签页滑动控制
isScrollable: true,
),
),
body: new TabBarView(
children: choices.map((Choice choice) {
return new Padding(
padding: const EdgeInsets.all(16.0),
child: new ChoiceDidi(
choice: choice,
),
);
}).toList(),
),
),
),
);
}
}
//定义
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
//出行方式
const List<Choice> choices = <Choice>[
Choice(title: '自行车', icon: Icons.directions_bike),
Choice(title: '自驾', icon: Icons.directions_car),
Choice(title: '乘船', icon: Icons.directions_boat),
Choice(title: '公交', icon: Icons.directions_bus),
Choice(title: '火车', icon: Icons.directions_railway),
Choice(title: '步行', icon: Icons.directions_walk),
Choice(title: '灰机', icon: Icons.airplanemode_active),
];
class ChoiceDidi extends StatelessWidget {
const ChoiceDidi({Key key, this.choice}) : super(key: key);
final Choice choice;
@override
Widget build(BuildContext context) {
// TODO: implement build
//主题颜色
final TextStyle textStyle = Theme.of(context).textTheme.display1;
//包装
return Card(
color: Colors.white,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
//居中
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(
choice.icon,
size: 128.0,
color: textStyle.color,
),
Text(
choice.title,
style: textStyle,
)
],
),
),
);
}
}
void main() {
runApp(DidiSample());
}