1、flutter的开始
1、认识文件夹
文件夹名称 | 作用 |
---|---|
android | android平台相关代码 |
ios | ios平台相关代码 |
lib | flutter相关代码,主要编写的代码放入该文件夹 |
test | 用于存放测试代码 |
pubspec.yaml | 配置文件,项目相关信息,一般存放第三方库的依赖 |
2、入口文件/入口方法
入口文件:flutter项目的lib目录里面都有一个main.dart这个文件就是flutter的入口文件
入口方法:main.dart文件中的
void main() {
runApp(MyApp());
}
//也可也简写一下
void main()=>runApp(MyApp());
其中main方法是dart的入口方法。runApp方法是flutter的入口方法。MyApp是自定义的一个组件。
2、flutter基本
从最根本的开始哦。
1、Helloworld
import 'package:flutter/material.dart';
void main() {
runApp( Center(
child: Text(
'CDX',
textDirection: TextDirection.ltr,
)
));
}
实现效果:
2、自定义组件
在flutter中自定义组件其实就是一个类,这个类需要继承StatelessWidget/StatefulWidget。
StatelessWidget:是无状态组件,状态不可变的widget。
StatefulWidget:是有状态组件,持有的状态可能在widget生命周期改变。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'CDX111',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
color: Colors.yellow,
),
));
}
}
实现效果:
3、组件:MaterialApp/Scaffold
1、MaterialApp组件是一个方便的Widget,它封装了应用程序实现Material Design所需要的一些Widget。一般作为顶层widget使用。
2、Scaffold组件是Material Design布局结构的基本实现。此类提供了用于显示drawer、snackbar和底部sheet的API。
代码块:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'CDX111',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
color: Colors.yellow,
),
));
}
}
完整代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'CDX111',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
color: Colors.yellow,
),
));
}
}
实现效果:
4、组件:Container/Text 详解
1、Container组件
该组件可以被用来看作是我们之前的一个div,其实他就是一个对象,我们来看一下他的构造函数吧。
Container组件属性描述
属性名 | 类型 | 说明 |
---|---|---|
key | Key | Container 一标识符,用于查找更新 |
alignment | AlignmentGeometry | 控制child 的对齐方式,如果Container或者 Container 父节点尺寸大于child 的尺寸,这个属性设置会起作用,有很多种对齐方式 |
padding | EdgelnsetsGeometry | Decoration内部的空白区域,如果有child的话,child 位于padding 内部 |
color | Color | 用来设置 Contain 背景色,如果foregroundDecoration设置的话,可能会遮盖color效果 |
decoration | Decoration | 绘制在child后面的装饰,设置了 Decoration 话,就不能设置color 属性,否则会报错,此时应该在 Decoration中进行颜色的设置 |
foregroundDecoration | Decoration | 绘制在child前面的装饰 |
width | double | Container的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局 |
height | double | Container的高度,设置为double.infinity可以强制在高度上撑满 |
constraints | BoxConstraints | 添加到child上额外的约束条件 |
margin | EdgelnsetsGeometry | 围绕在Decoration和child之外的空白区域,不属于内容区域 |
transform | Matrix4 | 设置Container的变换矩阵,类型为Matrix4 |
child | Widget | Container中的内容Widget |
2、Text组件
Text组件属性描述
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
data | String | 数据为要显示的文本 | |
maxLines | int | 0 | 文本显示的最大行数 |
style | TextStyle | null | 文本样式,可定义文本的字体大小、颜色、粗细等 |
textAlign | TextAlign | TextAlign.center | 文本水平方向对齐方式,取值有center、end、justify、left、right、start、values |
textDirection | TextDirection | TextDirection.ltr | 文本书写方向。ltr从左到右,rtl从右到左 |
textScaleFactor | double | 1.0 | 字体缩放系数 |
textSpan | TextSpan | null | 文本块 |
3、示例
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Text(
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
textAlign: TextAlign.center,
overflow: TextOverflow.fade,
style: TextStyle(
fontSize: 16.0,
color: Colors.red,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.italic,
decoration: TextDecoration.lineThrough,
decorationColor: Colors.white,
decorationStyle: TextDecorationStyle.dashed),
),
height: 300.0,
width: 300.0,
decoration: BoxDecoration(
color: Colors.green,
border: Border.all(color: Colors.blue, width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(150))
),
transform: Matrix4.rotationZ(0.3),
),
);
}
}
效果:
5、图片组件
基础代码块:(本节代码基础部分,其余效果展示代码均在HomeContent中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介绍
1、new Image:从ImageProvideer 获取图片
2、new Image.asset:加载资源图片
3、new Image.file:加载本地图片文件
4、new Image.netWork:加载网络图片
5、new Image.memory:加载Uint8List资源图片。
Image组件属性描述
属性名 | 类型 | 说明 |
---|---|---|
image | ImageProvider | 抽象类,需要自己实现获取图片数据的操作 |
width/hei ght | double | Image显示区域的宽度和高度设置 |
fit | Boxfit | 图片填充模式 |
color | Color | 图片颜色 |
colorBlendMode | BlendMode | 在对图片进行手动处理的时候,可能会用到图片混合如改变图片的颜色。此属性可以对颜色进行混合处理。 |
alignment | Alignment | 控制图片的摆放位置 |
repeat | ImageRepeat | 设置图片重复模式 |
centerSlice | Rect | 当图片需要被拉伸时使用 |
matchTextDirection | booI | 该属性与Directionlity配合使用 |
gaplessPlayback | bool | 当ImageProvide发生变化后,重新加载图片的过程中,原图片的展示是否保留 |
BoxFit取值描述
取值 | 描述 |
---|---|
Boxfit.fill | 全图显示,显示可能拉伸,充满 |
Boxfit.contain | 全图显示,显示原比例,不需充满 |
Boxfit. cover | 显示可能拉伸,可能裁剪,充满 |
BoxFit.fitWidth | 显示可能拉伸,可能裁剪,宽度充满 |
BoxFit.fitHeight | 显示可能拉伸,可能裁剪,高度充满 |
Boxfit.none | 原始大小 |
BoxFit.scaleDown | 效果和BoxFit.contain差不多,但是此属性不允许显示超过源图片大小,即可小不可大 |
2、远程图片示例
mage.network(src)
简单示例:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Image.network(
"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
colorBlendMode: BlendMode.screen,
fit: BoxFit.cover,),
width: 300,
height: 300,
decoration: BoxDecoration(
color: Colors.green,
),
),
);
}
}
效果:
3、实现圆角以及圆形图片
1、使用borderRadius和BoxFit.cover实现
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 300,
height: 300,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(150),//*********
image: DecorationImage(
image: NetworkImage( "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
),
fit: BoxFit.cover,//************
),
),
));
}
}
效果:
2、使用ClipOval实现
1、首先看clipOval处理的效果
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: ClipOval(
child: Image.network("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",),
),
));
}
}
效果:
2、继续变圆
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: ClipOval(
child: Image.network("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1675144683,641372710&fm=26&gp=0.jpg",
height: 300,
width: 300,
fit: BoxFit.cover,),
),
));
}
}
效果:
2、本地图片
1、相关文件夹的创建与配置文件修改
2、示例
1、代码
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Image.asset("images/1.jpg"),
));
}
}
2、效果
6、列表组件
基础代码块:(本节代码基础部分,其余效果展示代码均在HomeContent中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: HomeContent(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介绍
列表大致有以下分类
1、水平的列表
2、垂直的列表
3、数据量非常大的列表
4、矩阵式的列表
ListView组件的基本属性
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
scrollDirection | Axis | Axis.vertical | 列表的排列方向,Axis.vertical为垂直方法式默认值,Axis.horizontal为水平方法 |
padding | EdgelnsetsGeometry | 列表内部的空白区域,如果有child的话,child位于padding内部 | |
reverse | bool | false | 组件排列反向 |
children | List | 列表元素,注意List元素全部为Widget |
2、垂直列表
代码:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
ListTile(
leading: Image.asset("images/1.jpg"),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
trailing: Icon(Icons.search),
),
ListTile(
leading: Icon(Icons.padding),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
leading: Icon(Icons.games),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
leading: Icon(Icons.ac_unit_sharp),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
ListTile(
leading: Icon(Icons.tab),
title: Text("xxxxxxxxxxxxxxxxxxxxx"),
subtitle: Text("ccccccccccccccccccc"),
),
],
);
}
}
效果:
3、水平列表
代码:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 200,
child:ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.green,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.grey,
),
Container(
width: 100,
height: 100,
color: Colors.deepOrange,
),
],
)
);
}
}
效果:
4、动态列表
代码:
class HomeContent extends StatelessWidget {
List<Widget> getData() {
List<Widget> list = new List();
for (var i = 1; i <= 7; i++) {
list.add(ListTile(
title: Text("xxxxxx$i个"),
));
}
return list;
}
@override
Widget build(BuildContext context) {
return Container(child: ListView(children: this.getData()));
}
}
ListView.builder
class HomeContent extends StatelessWidget {
List list = new List();
HomeContent() {
for (var i = 1; i <= 7; i++) {
list.add("xxxxxx$i个");
}
}
@override
Widget build(BuildContext context) {
return Container(child: ListView.builder(
itemCount: this.list.length,
itemBuilder: (context,index){
return ListTile(
title: Text(this.list[index]),
);
},
));
}
}
效果:
7、GridView组件
基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
GridView组件属性及描述
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
scrollDirection | Axis | Axis.vertical | 滚动的方向,有垂直和水平两种,默认为垂直方向 |
reverse | bool | false | 默认是从上或者左向下或者向右滚动的,这个属性控制是否反向,默认值为false,即不反向滚动 |
controller | ScrollController | 控制child滚动时候的位置 | |
primary | bool | 是否是与父节点的PrimaryScrollcontroller所关联的主滚动视图 | |
physics | ScrollPhysics | 滚动的视图如何响应用户的输入 | |
shrinkWrap | bool | false | 滚动方向的滚动视图内容是否应该由正在查看的内容所决定 |
padding | EdgeinsetsGeometry | 四周的空白区域 | |
gridDelegate | SliverGridDelegate | 控制GridView中子节点布局的delegate | |
cacheExtent | double | 缓存区域 |
1、通过GridView.count实现网格布局
代码:
class Demo extends StatelessWidget {
List<Widget> getData() {
List<Widget> list = new List();
for (var i = 0; i < 20; i++) {
list.add(Container(
alignment: Alignment.center,
child: Text(
'xxxxx $i xxxx',
style: TextStyle(color: Colors.white,fontSize: 20),
),
color: Colors.blue,
));
}
return list;
}
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisSpacing: 10.0, //水平子Widget之间的距离
mainAxisSpacing: 10.0, //垂直widget之间距离
padding: EdgeInsets.all(10),
crossAxisCount: 3, //控制一行有多少个Widget
childAspectRatio: 0.7,//宽度和高度的比例
children: this.getData(),
);
}
}
效果:
2、通过GridView.builder实现网格布局
代码:
class Demo extends StatelessWidget {
Widget getData(context, index) {
return Container(
child: Column(
children: <Widget>[
Image.asset("images/1.jpg"),
SizedBox(height: 12),
Text(
"xxxxxxxx",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20),
)
],
),
decoration: BoxDecoration(
border: Border.all(color: Colors.blue, width: 1),
),
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
// padding: EdgeInsets.all(10),
// crossAxisCount: 3, //控制一行有多少个Widget
// childAspectRatio: 0.7,//宽度和高度的比例
// children: this.getData(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10.0, //水平子Widget之间的距离
mainAxisSpacing: 10.0, //垂直widget之间距离
crossAxisCount: 3, //控制一行有多少个Widget
),
itemCount: 10,
itemBuilder: this.getData,
);
}
}
效果:
8、页面布局 Padding/Row/Column/Expanded
基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
GridView组件属性及描述
1、Padding组件
在html中常见的布局标签都有padding属性,但是Fliuuter中很多widget是没有padding属性的。这时候我们可以用Padding组件处理容器与子元素之间的间距
属性 | 说明 |
---|---|
padding | padding值,EdgeInsetss设置填充的值 |
child | 子组件 |
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.count(
padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
crossAxisCount: 3, //控制一行有多少个Widget
childAspectRatio: 1.7,//宽度和高度的比例
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.asset("images/1.jpg",fit: BoxFit.cover,),
),
],
);
}
}
效果:
2、Row水平布局组件
属性介绍:
属性 | 说明 |
---|---|
mainAxisAlignment | 主轴的排序方式 |
crossAxisAlignment | 次轴的排序方式 |
children | 组件子元素 |
3、Column垂直布局组件
实现一个图标组件:实现传入图标(颜色和大小动态)
代码:
class IconDemo extends StatelessWidget {
double size = 32.0;
Color color = Colors.red;
IconData icon;
IconDemo(this.icon, {this.color, this.size});
@override
Widget build(BuildContext context) {
return Container(
height: 100.0,
width: 100.0,
color: this.color,
child: Center(
child: Icon(
Icons.home,
size: 32,
color: Colors.white,
),
),
);
}
}
通过上述组件测试Row的排序
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 600.0,
width: 600.0,
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
IconDemo(
Icons.home,
color: Colors.green,
),
IconDemo(
Icons.search,
color: Colors.red,
),
IconDemo(
Icons.fit_screen,
color: Colors.green,
),
],
)
);
}
}
class IconDemo extends StatelessWidget {
double size = 32.0;
Color color = Colors.red;
IconData icon;
IconDemo(this.icon, {this.color, this.size});
@override
Widget build(BuildContext context) {
return Container(
height: 100.0,
width: 100.0,
color: this.color,
child: Center(
child: Icon(
Icons.home,
size: 32,
color: Colors.white,
),
),
);
}
}
效果:
4、Expanded组件
Flutter中Expanded组件类似Web中的Flex布局
Expanded可以用在Row和Column布局中
属性 | 说明 |
---|---|
flex | 元素占整个父Row/Column的比例 |
child | 子元素 |
代码:(未包含上述IconDemo组件的代码)
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 1,
child: IconDemo(
Icons.home,
color: Colors.green,
),
),
Expanded(
flex: 2,
child: IconDemo(
Icons.search,
color: Colors.red,
),
),
],
);
}
}
效果:
5、相关案例
实现一个类似于下图的布局
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
height: 200,
color: Colors.blue,
child: Text("xxxxxxxxxx"),
),
)
],
),
SizedBox(height: 10),
Row(children: <Widget>[
Expanded(
flex: 2,
child: Container(
height: 180,
child: Image.asset(
"images/1.jpg",
fit: BoxFit.cover,
))),
Expanded(
flex: 1,
child: Container(
height: 180,
child: ListView(children: <Widget>[
Container(
height: 85,
child: Image.asset(
"images/1.jpg",
fit: BoxFit.cover,
)),
SizedBox(height: 10),
Container(
height: 85,
child: Image.asset(
"images/1.jpg",
fit: BoxFit.cover,
))
]))),
]),
],
);
}
}
效果:
9、页面布局 Stack层叠组件/Stack与Aligin/Stack与Positioned
基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、Stack组件
属性 | 说明 |
---|---|
alignment | 配置所有子元素的显示位置 |
children | 子组件 |
stack效果:有点像元素重叠一样,下面展示文字和容器效果
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
height: 400,
width: 300,
color: Colors.red,
),
Text("xxxxxxxxxxx")
],
);
}
}
效果:
通过alignment属性进行位置移动
还可以是坐标
alignment: Alignment(0,0),
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
// alignment: Alignment.center,
// alignment: Alignment(0,0),
alignment: Alignment.center,
children: <Widget>[
Container(
height: 400,
width: 300,
color: Colors.red,
),
Text("xxxxxxxxxxx")
],
);
}
}
效果:
2、align/positiond
上述stack如果里面有两个文本的话,就会导致两个文本出现重叠的现象如下:
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
// alignment: Alignment.center,
// alignment: Alignment(0,0),
alignment: Alignment.center,
children: <Widget>[
Container(
height: 400,
width: 300,
color: Colors.red,
),
Text("xxxxxxxxxxx"),
Text("ddddddddddd"),
],
);
}
}
效果:
使用align
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 400,
width: 400,
color: Colors.blue,
child: Stack(children: <Widget>[
Align(
alignment: Alignment.topLeft,
child: Icon(Icons.help, size: 40, color: Colors.white),
),
Align(
alignment: Alignment.center,
child: Icon(Icons.search, size: 40, color: Colors.white),
),
Align(
alignment: Alignment.bottomRight,
child: Icon(Icons.home_filled, size: 40, color: Colors.white),
),
]),
),
);
}
}
效果:
使用positiond
属性 | 说明 |
---|---|
top | 子元素距离顶部的距离 |
bottom | 子元素距离底部的距离 |
left | 子元素距离左侧的距离 |
right | 子元素距离右侧的距离 |
child | 子组件 |
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 400,
width: 400,
color: Colors.blue,
child: Stack(children: <Widget>[
Positioned(
left: 10,
child: Icon(Icons.help, size: 40, color: Colors.white),
),
Positioned(
bottom: 0,
child: Icon(Icons.search, size: 40, color: Colors.white),
),
Positioned(
right: 0,
child: Icon(Icons.home_filled, size: 40, color: Colors.white),
),
]),
),
);
}
}
效果:
10、AspectRatio组件/Card组件
基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、AspectRatio
AspectRatio的作用是根据设置调整子元素child的宽高比。
AspectRatio首先会在布局限制条件允许的范围内尽可能的扩展,widget的宽度是由宽度和比率决定的,类似于BoxFit中的contain,按照固定比率去尽量占满区域。
如果在满足所有限制条件过后无法找到一个可行的尺寸,AspectRatio最终将会去优先适应布局限制条件,而忽略所设置的比率
属性 | 说明 |
---|---|
aspectRatio | 宽高比,最终可能不会根据这个值去布局,具体要看综合因素,外层是否允许按照这种比例进行布局,这只是一个参考值 |
child | 子组件 |
代码:(长是高的2倍例子)
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 200,
child: AspectRatio(
aspectRatio: 2.0/1.0,//外层的200,会是里面的container长200高100
child: Container(
color: Colors.red,
),
),
);
}
}
2、Card
Card是卡片组件块,内容可以由大多数类型的Widget构成,Card具有圆角和阴影,这让它看起来有立体感。
属性 | 说明 |
---|---|
margin | 外边距 |
child | 子组件 |
Shape | Card的阴影效果,默认的阴影效果为圆角的长方形边。 |
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Card(
margin:EdgeInsets.all(10),
child: Column(
children: <Widget>[
ListTile(
title:Text('chidaoxian'),
subtitle: Text('前端开发工程师'),
),
ListTile(
title:Text('电话:12323432141234123'),
),
ListTile(
title:Text('地址:xxxxxx'),
),
],
),
),
Card(
margin:EdgeInsets.all(10),
child: Column(
children: <Widget>[
ListTile(
title:Text('chidaoxian'),
subtitle: Text('前端开发工程师'),
),
ListTile(
title:Text('电话:12323432141234123'),
),
ListTile(
title:Text('地址:xxxxxx'),
),
],
),
),
],
);
}
}
效果:
11、Wrap组件
基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介绍
wrap组件可以实现流布局,单行的Wrap跟Column表现几乎一致,单列的Wrap则跟Row表现几乎一致。但Row与Column都是单行单列,Wrap则突破了这个限制,mainAxis上空间不足时,则向crossAxis上去扩展显示。
属性 | 说明 |
---|---|
direction | 主轴的方法,默认水平 |
alignment | 主轴的对齐方式 |
spacing | 主轴方向上的间距 |
textDirection | 文本方向 |
verticalDirection | 定义了children摆放顺序,默认是down,见flex相关属性介绍 |
runAlignment | run的对齐方式。run可以理解为新的行或者列,如果是水平方向布局的话,run可以理解为新的一行 |
runSpacing | run的间距 |
2、wrap实例
代码:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Wrap(
spacing:10,
// runSpacing:5,
children: <Widget>[
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
MyButton('xxx'),
]);
}
}
class MyButton extends StatelessWidget {
final String text;
const MyButton(this.text, {Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text(this.text),
textColor: Theme.of(context).accentColor,
onPressed: () {},
);
}
}
效果:
12、StatefulWidget有状态组件、页面上绑定数据、改变页面数据
基础代码块:(本节代码基础部分,其余效果展示代码均在Demo中)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Demo(),
),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
1、介绍
StatefulWidget是有状态组件,持有的状态可能在Widget生命周期改变。通俗的讲:如果我们想改变页面中的数据的话这个时候就需要用到StatefulWidget。
2、有状态组件/数据绑定
代码:
class Demo extends StatefulWidget {
Demo({Key key}) : super(key: key);
@override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
int countNum = 0;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SizedBox(height: 20,),
Chip(label: Text('${this.countNum}')),
SizedBox(height: 20,),
RaisedButton(
child: Text('按钮'),
onPressed: (){
setState(() {
this.countNum++;
});
},
)
],
);
}
}
效果:
13、ButtonNavigationBar组件
1、介绍
ButtonNavigationBar 是底部导航条,可以让我们定义底部Tab切换,buttonNavigationBar是Scaffold组件参数。
属性名 | 类型 | 说明 |
---|---|---|
currentlndex | int | 当前索引,用来切换按钮控制 |
fixedColor | Color | 选中按钮的颜色。如果没有指定值,则用系统主题色 |
iconSize | double | 按钮图标大小 |
items | List | 底部导航调按钮集。每一项是一个BottomNavigationBarItem,有icon图标及title文本属性 |
onTap | ValueChanged | 按下其中某一个按钮回调事件。需要根据返回的索引设置当前索引 |
2、实例
1、效果:
底部导航切换页面效果:
代码介绍:
代码:
1、main.dart的代码
import 'package:flutter/material.dart';
import 'package:flutter_app01/pages/tabs/Home.dart';
import 'pages/tabs/Tabs.dart';
import 'pages/tabs/ddd.dart';
import 'pages/tabs/Setting.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Tabs(),
theme: ThemeData(
primarySwatch: Colors.green,
),
);
}
}
class Tabs extends StatefulWidget {
Tabs({Key key}) : super(key: key);
@override
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int currentIndex = 0;
List pageList = [
HomePage(),
SettingPage(),
DDDPage(),
];
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: this.pageList[this.currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: this.currentIndex,
onTap: (int index) {
setState(() {
this.currentIndex = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.my_library_books),
label: '我的',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings_applications),
label: '设置',
),
],
),
),
);
}
}
2、Tabs.dart的代码
import 'package:flutter/material.dart';
class Tabs extends StatefulWidget {
Tabs({Key key}) : super(key: key);
@override
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int currentIndex = 0;
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text('flutter cdx'),
),
body: Text('xxx'),
bottomNavigationBar: BottomNavigationBar(
currentIndex: this.currentIndex,
onTap: (int index) {
setState(() {
this.currentIndex = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.my_library_books),
label: '我的',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings_applications),
label: '设置',
),
],
),
),
);
}
}
3、Home.dart的代码(Home.dart/Setting.dart代码类似)
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('HomePage'),
);
}
}
14、Flutter中的基本路由
flutter中的路由通俗的讲就是页面跳转。在flutter中通过Navigator组件管理路由导航。并提供了管理堆栈的方法。如:Navigator.push 和Navigator.pop
flutter中给我们提供了两种配置路由跳转的方式:1、基本路由 2、命名路由
1、简单路由跳转
代码:
import 'package:flutter/material.dart';
import '../Search.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('跳转搜索页面'),
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (context)=> SearchPage()
)
);
},
),
],
);
}
}
2、跳转传值
代码:
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
SearchPage({Key key}) : super(key: key);
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
String title ;
_SearchPageState({this.title = 'cdx'});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("${this.title}页面"),
),
body: Text("内容区域"),
);
}
}
3、返回
代码:
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
SearchPage({Key key}) : super(key: key);
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
String title ;
_SearchPageState({this.title = 'cdx'});
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Text('返回'),
onPressed: (){
Navigator.of(context).pop();
},
),
appBar: AppBar(
title: Text("${this.title}页面"),
),
body: Text("内容区域"),
);
}
}
效果:
15、Flutter命名路由
1、不携带参数
main.dart文件配置:**
路由跳转方式:
2、携带参数
Routes.dart文件
import 'package:flutter/material.dart';
import 'package:flutter_app01/pages/tabs/Tabs.dart';
import 'package:flutter_app01/pages/tabs/ddd.dart';
import 'package:flutter_app01/pages/tabs/Setting.dart';
import 'package:flutter_app01/pages/Search.dart';
import 'package:flutter_app01/pages/tabs/Home.dart';
final routes = {
'/': (context, {arguments}) => Tabs(),
'/home': (context, {arguments}) => HomePage(),
'/ddd': (context, {arguments}) => DDDPage(),
'/setting': (context, {arguments}) => SettingPage(),
'/search': (context, {arguments}) => SearchPage(arguments: arguments),
};
//主要方法
var onGenerateRoute = (RouteSettings settings) {
final String name = settings.name;
final Function pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context, argumens: settings.arguments));
return route;
} else {
final Route route = MaterialPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
};
main.dart文件
import 'package:flutter/material.dart';
import 'package:flutter_app01/routes/Routes.dart';
void main() {
runApp(MyApp());
}
//自定义组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.green,
),
// home: Tabs(),
initialRoute: '/', //初始化的时候加载的路由
onGenerateRoute: onGenerateRoute,
);
}
}
16、路由替换/返回根路由
1、替换路由
就是替换当前的页面。
2、返回跟路由
待入的组件表格属性介绍
Form组件
属性名 | 类型 | 说明 |
---|---|---|
key | Key | 组件在整个Widget树中的key值 |
autovalidate | bool | 是否自动提交表单 |
child | Widget | 组件child只能有一个子组件 |
onChanged | VoidCallback | 当FormFiled值改变时的回调函数 |
TextFromField组件
属性名 | 类型 | 说明 |
---|---|---|
autovalidate | bool | 自动验证值 |
initialValue | T | 表单字段初始值 |
onSaved | FormFieldSetter | 当Form表单调用保存方法Save时回调函数 |
validator | FormFieldValidator | Form表单验证器 |
Material Design风格组件
组件名称 | 中文名称 | 简单说明 |
---|---|---|
AppBar | 应用按钮组件 | 应用的工具按钮 |
AlertDialog | 对话框组件 | 有操作按钮的对话框 |
BottomNavigationBar | 底部导航条组件 | 底部导航条,可以很容易地在tap之间切换和浏览顶级视图 |
Card | 卡片组件 | 带有边框阴影的卡片组件 |
Drawer | 抽屉组件 | Drawer抽屉组件可以实现类似抽屉拉开关闭的效果 |
FloatingActionButton | 浮动按钮组件 | 应用的主要功能操作按钮 |
FlatButton | 扁平按钮组件 | 扁平化风格的按钮 |
MaterialApp | Material应用组件 | Material App代表使用纸墨设计风格的应用 |
PopupMenuButton | 弹出菜单组件 | 弹出菜单按钮 |
Scaffold | 脚手架组件 | 实现了基本的Material Design 布局 |
SnackBar | 轻量提示组件 | 一个轻量级消息提示组件,在屏幕的底部显示 |
SimpleDialog | 简单对话框组件 | 简单对话框组件,只起提示作用,没有交互 |
TabBar | 水平选项卡及视图组件 | 一个显示水平选项卡的Material Design组件 |
TextField | 文本框组件 | 可接受应用输入文本的组件 |
MaterialApp
属性名 | 类型 | 说明 |
---|---|---|
title | String | 应用程序的标题。该标题出现在如下位置:Android:任务管理器的程序快照之上 IOS:程序切换管理器 |
theme | ThemeData | 定义应用所使用的主题颜色。可以指定一个主题中每个控件的颜色 |
color | Color | 应用的主要颜色值,即 primary color |
home | Widget | 这个是一个Widget对象,用来定义当前应用打开时,所显示的界面 |
routes | Map<String,WidgetBuider> | 定义应用中页面跳转规则 |
initialRoute | String | 初始化路由 |
onGenerateRoute | RouteFactory | 路由回调函数。当通过Navigator.of(context).pushNamed跳转路由时,在routes查找不到时,会调用该方法 |
onLocaleChanged | 当系统修改语言的时候,会触发这个回调 | |
navigatorObservers | List | 导航观察器 |
debugShowMaterialGrid | bool | 是否显示纸墨设计基础布局网格,用来调试UI的工具 |
showPerformanceOverlay | bool | 显示性能标签 |
Scaffold
属性名 | 类型 | 说明 |
---|---|---|
appBar | AppBar | 显示在界面顶部的一个AppBar |
body | Widget | 当前界面所显示的主要内容 |
floatingActionButton | Widget | 在Material Design中定义的一个功能按钮 |
persistentFooterButtons | List | 在固定在下方显示的按钮 |
drawer | Widget | 侧边栏组件 |
bottomNavigationBar | Widget | 显示在底部的导航栏按钮栏 |
backgroundColor | Color | 背景颜色 |
resizeToAvoidBottomPadding | bool | 控制界面内容body是否重新布局来避免底部被覆盖,比如当键盘显示时,重新布局避免被键盘盖住内容。默认值为true |
AppBar及SliverAppBar组件
属性名 | 类型 | 默认值 |
---|---|---|
leading | Widget | null |
title | Widget | null |
actions | List | null |
bottom | PreferredSize Widget | null |
elevation | double | 4 |
flexibleSpace | Widget | null |
backgroundColor | Color | ThemeData.primaryColor |
brightness | Brightness | ThemeData.primaryColorBrightness |
iconTheme | IconThemeData | ThemeData.primaryIconTheme |
textTheme | TextTheme | ThemeData.primaryTextTheme |
centerTitle | bool | true |
介绍:
属性名 | 说明 |
---|---|
leading | 在标题前面显示的一个组件,在首页通常显示应用的logo;在其他界面通常显示 |
title | Toolbar中主要内容,通常显示为当前界面的标题文字 |
actions | 一个Widget列表,代表Toolbar中所显示的菜单,对于通常的菜单,通常使用IconButton来表示,对于不太常用的菜单通常使用PopupMenuButton来显示为三点,点击后弹出二级菜单 |
bottom | 通常是TabBar。用来在Toolbar标题下面显示一个Tab导航栏 |
elevation | 纸墨设计中组件的z坐标顺序,对于可滚动的SliverAppBar,当SliverAppBar和内容同级的时候,该值为0,当内容咕哝的那个SliverAppBar变为ToolBar的时候,修改elevation |
flexibleSpace | 一个显示在AppBar下方的组件,高度和AppBar高度一样,可以实现一些特殊的效果,该属性通常在SliverAppBar中使用 |
backgroundColor | 背景色 |
brightness | AppBar的亮度,有白色和黑色两种主题 |
iconTheme | AppBar上图标的颜色、透明度和尺寸信息。默认值为ThemeData. primaryIcon Theme |
textTheme | AppBar上的文字样式 |
centerTitle | 标题是否居中显示,默认值根据不同的操作系统,显示方式不一样 |