共计 17537 个字符,预计需要花费 44 分钟才能阅读完成。
一.Text
1.TextAlign
// 对齐
child:Text(
'非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
textAlign:TextAlign.left,
)
/**
textAlign:TextAlign.left
* center: 文本以居中形式对齐, 这个也算比较常用的了。* left: 左对齐,经常使用,让文本居左进行对齐,效果和 start 一样。* right : 右对齐,使用频率也不算高。* start: 以开始位置进行对齐,类似于左对齐。* end: 以为本结尾处进行对齐,不常用。有点类似右对齐
*/
2.maxLines
设置最多显示的行数,比如我们现在只显示 1 行
child:Text(
'非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
textAlign:TextAlign.left,
maxLines: 1,
)
3.overflow
overflow 属性是用来设置文本溢出时,如何处理
child:Text(
'非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
textAlign:TextAlign.left,
overflow: clip,
)
/*
* clip:直接切断,剩下的文字就没有了
* ellipsis: 在后边显示省略号,体验性较好
* fade: 溢出的部分会进行一个渐变消失的效果
*
*
*/
4.style
style 属性较多
child:Text(
'非常喜欢前端,并且愿意为此奋斗一生。我希望可以出 1000 集免费教程。',
textAlign:TextAlign.left,
overflow:TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize:25.0,
color:Color.fromARGB(255, 255, 150, 150),
decoration:TextDecoration.underline,
decorationStyle:TextDecorationStyle.solid,
),
)
/*
inherit: true, // 为 false 的时候不显示
color: Color.fromARGB(255, 150, 150, 150), // 颜色
fontSize :22.0, // 字号
fontWeight: FontWeight.w700, // 字重,加粗也用这个字段 FontWeight.w700
fontStyle: FontStyle.italic , // FontStyle.normal FontStyle.italic 斜体
letterSpacing: 10.0, // 字符间距 就是单个字母或者汉字之间的间隔,可以是负数
wordSpacing: 15.0, // 字间距 句字之间的间距
textBaseline: TextBaseline.alphabetic, // 基线,两个值,字面意思是一个用来排字母的,一人用来排表意字的(类似中文)textBaseline: TextBaseline.ideographic
height: 1.0, // 当用来 Text 控件上时,行高(会乘以 fontSize, 所以不以设置过大)decoration: TextDecoration.overline, // 添加上划线
decoration: TextDecoration.lineThrough, // 添加删除线
decoration: TextDecoration.underline, // 添加下划线
decorationColor, // 划线的颜色
decorationStyle: TextDecorationStyle.dotted, // 这个 style 可能控制画实线,虚线,两条线,点, 波浪线等
debugLabel,
background: // 文本背景色
String fontFamily, // 字体
String package,
*/
二.Container 容器组件
Container(容器控件)在 Flutter 是经常使用的控件,它就相当于我们 HTML 里的 <div> 标签
1.padding 属性
padding 的属性就是一个内边距
child:Container(
child:new Text('Container 容器组件',
style: TextStyle(fontSize: 40.0)
),
alignment: Alignment.topLeft,
width:500.0,
height:400.0,
color: Colors.lightBlue,
padding:const EdgeInsets.all(10.0),
)
padding:const EdgeInsets.all(10.0),
设置 Container 的内边距是 10,左右上下全部为 10
padding:const EdgeInsets.fromLTRB(10.0,30.0,0.0,0.0)
可以满足我们分别设置上下左右,LTRB 分别代表左、上、右、下
2.margin 属性
child:Container(
child:new Text('Hello JSPang',
style: TextStyle(fontSize: 40.0)
),
alignment: Alignment.topLeft,
width:500.0,
height:400.0,
color: Colors.lightBlue,
padding:const EdgeInsets.fromLTRB(10.0,30.0,0.0,0.0),
margin: const EdgeInsets.all(10.0),
)
3.decoration 属性
decoration 是 container 的修饰器,主要的功能是设置背景和边框
比如你需要给背景加入一个渐变,和边框 这时候需要使用 BoxDecoration 这个类
注意:
需要注意的是如果你设置了 decoration,就不要再设置 color 属性了,因为这样会冲突
child:Container(child:new Text('Hello JSPang',style: TextStyle(fontSize: 40.0),),
alignment: Alignment.topLeft,
width:500.0,
height:400.0,
padding:const EdgeInsets.fromLTRB(10.0,30.0,0.0,0.0),
margin: const EdgeInsets.all(10.0),
decoration:new BoxDecoration(
gradient:const LinearGradient(colors:[Colors.lightBlue,Colors.greenAccent,Colors.purple]
),
border:Border.all(width:2.0,color:Colors.red)
)
)
三.Image 图片组件的使用
1. 加入图片的几种方式
1.Image.asset: 加载资源图片,就是加载项目资源目录中的图片, 加入图片后会增大打包的包体体积,用的是相对路径。
2.Image.network: 网络资源图片,意思就是你需要加入一段 http://xxxx.xxx 的这样的网络路 …。
3.Image.file: 加载本地图片,就是加载本地文件中的图片,这个是一个绝对路径,跟包体无关。
4.Image.memory: 加载 Uint8List 资源图片
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'Text widget',
home:Scaffold(
body:Center(
child:Container(
child:new Image.network(
'http://jspang.com/static/myimg/blogtouxiang.jpg',
scale:1.0,
),
width:300.0,
height:200.0,
color: Colors.lightBlue,
),
),
),
);
}
}
2.fit 属性的设置
fit 属性可以控制图片的拉伸和挤压,这些都是根据图片的父级容器来的,我们先来看看这些属性(建议此部分组好看视频理解)。
BoxFit.fill: 全图显示,图片会被拉伸,并充满父容器。
BoxFit.contain: 全图显示,显示原比例,可能会有空隙。
BoxFit.cover:显示可能拉伸,可能裁切,充满(图片要充满整个容器,还不变形)。
BoxFit.fitWidth:宽度充满(横向充满),显示可能拉伸,可能裁切。
BoxFit.fitHeight:高度充满(竖向充满), 显示可能拉伸,可能裁切。
BoxFit.scaleDown:效果和 contain 差不多,但是此属性不允许显示超过源图片大小,可小不可大
child:Container(
child:new Image.network(
'http://img.nodebook.top/nodebooklogo.jpg',
scale:1.0,
fit: BoxFit.fill
),
width:300.0,
height:200.0,
color: Colors.lightBlue,
)
3. 图片的混合模式
child:new Image.network(
'http://jspang.com/static/myimg/blogtouxiang.jpg',
color: Colors.greenAccent,
colorBlendMode: BlendMode.darken,
)
color:是要混合的颜色,如果你只设置 color 是没有意义的
colorBlendMode: 是混合模式,相当于我们如何混合。
4.repeat 图片重复
ImageRepeat.repeat : 横向和纵向都进行重复,直到铺满整个画布。
ImageRepeat.repeatX: 横向重复,纵向不重复。
ImageRepeat.repeatY:纵向重复,横向不重复
child:new Image.network(
'http://jspang.com/static/myimg/blogtouxiang.jpg',
repeat: ImageRepeat.repeat,
),
四.ListView 列表组件简介
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'JSPang Flutter Demo',
home:Scaffold(
appBar:new AppBar(title:new Text('ListView Widget')
),
body: new ListView(
children:<Widget>[
new ListTile(leading:new Icon(Icons.access_time),
title:new Text('access_time')
),
new ListTile(leading:new Icon(Icons.account_balance),
title:new Text('account_balance')
),
]
)
),
);
}
}
1. 两行列表
body: new ListView(
children:<Widget>[
new ListTile(leading:new Icon(Icons.access_time),
title:new Text('access_time')
),
new ListTile(leading:new Icon(Icons.account_balance),
title:new Text('account_balance')
),
]
),
---
2. 图片
body: new ListView(
children:<Widget>[
new Image.network('http://jspang.com/static/upload/20181111/G-wj-ZQuocWlYOHM6MT2Hbh5.jpg'),
new Image.network('http://jspang.com/static/upload/20181109/1bHNoNGpZjyriCNcvqdKo3s6.jpg'),
new Image.network('http://jspang.com/static/myimg/typescript_banner.jpg'),
new Image.network('http://jspang.com/static/myimg/smile-vue.jpg')
]
),
五. 横向列表的使用
其实还是使用我们的 ListView 组件,只是在 ListView 组件里加一个 ScrollDirection 属性。
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'Text widget',
home:Scaffold(
body:Center(
child:Container(
height:200.0,
child:new ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
new Container(
width:180.0,
color: Colors.lightBlue,
), new Container(
width:180.0,
color: Colors.amber,
), new Container(
width:180.0,
color: Colors.deepOrange,
),new Container(
width:180.0,
color: Colors.deepPurpleAccent,
),
],
)
),
),
),
);
}
}
1.scrollDirection 属性
ListView 组件的 scrollDirection 属性只有两个值,一个是横向滚动,一个是纵向滚动。默认的就是垂直滚动,所以如果是垂直滚动,我们一般都不进行设置。
Axis.horizontal: 横向滚动或者叫水平方向滚动。
Axis.vertical: 纵向滚动或者叫垂直方向滚动
组件化
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
body:Center(
child:Container(
height:200.0,
child:MyList() // => 组件化),
),
),
);
}
}
// MyList
class MyList extends StatelessWidget{
@override
Widget build(BuildContext context){
return ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
new Container(
width:180.0,
color: Colors.lightBlue,
), new Container(
width:180.0,
color: Colors.amber,
), new Container(
width:180.0,
color: Colors.deepOrange,
),new Container(
width:180.0,
color: Colors.deepPurpleAccent,
),
],
);
}
}
六. 动态列表的使用
List 类型的使用
List 是 Dart 的集合类型之一, 其实你可以把它简单理解为数组(反正我是这么认为的) , 它的声明有几种方式:
var myList = List(): 非固定长度的声明。
var myList = List(2): 固定长度的声明。
var myList= List<String>(): 固定类型的声明方式。
var myList = [1,2,3]: 对 List 直接赋值。
void main () => runApp(MyApp(items: new List<String>.generate(1000, (i)=> "Item $i")
));
generate 方法传递两个参数,第一个参数是生成的个数,第二个是方法
import 'package:flutter/material.dart';
void main () => runApp(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){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
body:new ListView.builder(
itemCount:items.length,
itemBuilder:(context,index){
return new ListTile(title:new Text('${items[index]}'),
);
}
)
),
);
}
}
七.GridView 网格列表组件
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
body:GridView.count(padding:const EdgeInsets.all(20.0),
crossAxisSpacing: 10.0,
crossAxisCount: 3,
children: <Widget>[const Text('I am Jspang'),
const Text('I love Web'),
const Text('jspang.com'),
const Text('我喜欢玩游戏'),
const Text('我喜欢看书'),
const Text('我喜欢吃火锅')
],
)
),
);
}
}
padding: 表示内边距,这个小伙伴们应该很熟悉。
crossAxisSpacing: 网格间的空当,相当于每个网格之间的间距。
crossAxisCount: 网格的列数,相当于一行放置的网格数量。
2. 加入图片
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
body:GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 2.0,
crossAxisSpacing: 2.0,
childAspectRatio: 0.7
),
children: <Widget>[new Image.network('http://img5.mtime.cn/mt/2018/10/22/104316.77318635_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/10/10/112514.30587089_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/13/093605.61422332_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/07/092515.55805319_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/21/090246.16772408_135X190X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/17/162028.94879602_135X190X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/19/165350.52237320_135X190X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/16/115256.24365160_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/20/141608.71613590_135X190X4.jpg',fit: BoxFit.cover),
],
)
),
);
}
}
childAspectRatio: 宽高比,这个值的意思是宽是高的多少倍,如果宽是高的 2 倍,那我们就写 2.0,如果高是宽的 2 倍,我们就写 0.5
一. 水平布局 Row 的使用
Flutter 中的 row 控件就是水平控件,它可以让 Row 里边的子元素进行水平排列
Row 控件可以分为灵活排列和非灵活排列两种
1. 不灵水平布局
从字面上就可以理解到,不灵活就是根据 Row 子元素的大小,进行布局。如果子元素不足,它会留有空隙,如果子元素超出,它会警告。
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('水平方向布局'),
),
body:new Row(
children: <Widget>[
new RaisedButton(onPressed: (){ },
color:Colors.redAccent,
child:new Text('红色按钮')
),
new RaisedButton(onPressed: (){ },
color:Colors.orangeAccent,
child: new Text('黄色按钮'),
),
new RaisedButton(onPressed: (){ },
color:Colors.pinkAccent,
child:new Text('粉色按钮')
)
],
)
),
);
}
}
这时候你会发现的页面已经有了三个按钮,但这三个按钮并没有充满一行,而是出现了空隙。这就是不灵活横向排列造成的。它根据子元素的大小来进行排列。如果我们想实现充满一行的效果,就要使用灵活水平布局了
2. 灵活水平布局
在按钮的外边加入 Expanded 就可以了
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('水平方向布局'),
),
body:new Row(
children: <Widget>[
Expanded(child:new RaisedButton(onPressed: (){ },
color:Colors.redAccent,
child:new Text('红色按钮')
)),
Expanded(child:new RaisedButton(onPressed: (){ },
color:Colors.orangeAccent,
child: new Text('黄色按钮'),
)
),
Expanded(child:new RaisedButton(onPressed: (){ },
color:Colors.pinkAccent,
child:new Text('粉色按钮')
)
)
],
)
),
);
}
}
3. 灵活和不灵活的混用
中间的按钮大,而两边的按钮保持真实大小
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('水平方向布局'),
),
body:new Row(
children: <Widget>[
new RaisedButton(onPressed: (){ },
color:Colors.redAccent,
child:new Text('红色按钮')
),
Expanded(child:new RaisedButton(onPressed: (){ },
color:Colors.orangeAccent,
child: new Text('黄色按钮'),
)
),
new RaisedButton(onPressed: (){ },
color:Colors.pinkAccent,
child:new Text('粉色按钮')
)
],
)
),
);
}
}
二. 垂直布局 Column 组件
1. 三行文字布局
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('垂直方向布局'),
),
body:Column(
children: <Widget>[Text('I am JSPang'),
Text('my website is jspang.com'),
Text('I love coding')
],
crossAxisAlignment: CrossAxisAlignment.start
)
),
);
}
}
CrossAxisAlignment.star:居左对齐。
CrossAxisAlignment.end:居右对齐。
CrossAxisAlignment.center:居中对齐。
2. 主轴和副轴的辨识
mainAxisAlignment 主轴的对齐方式
main 轴:如果你用 column 组件,那垂直就是主轴,如果你用 Row 组件,那水平就是主轴。
cross 轴:cross 轴我们称为幅轴,是和主轴垂直的方向。比如 Row 组件,那垂直就是幅轴,Column 组件的幅轴就是水平方向的
1. 垂直居中
mainAxisAlignment: MainAxisAlignment.center
3. 水平方向相对屏幕居中
让文字相对于水平方向居中,我们如何处理?其实只要加入 Center 组件就可以轻松解决
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('垂直方向布局'),
),
body:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Center(child:Text('I am JSPang')),
Center(child:Text('my website is jspang.com')),
Center(child:Text('I love coding'))
],
)
),
);
}
}
4.Expanded 属性的使用
在学习水平布局的时候我们对 Expanded 有了深刻的理解,它就是灵活布局。比如我们想让中间区域变大,而头部区域和底部根据文字所占空间进行显示
body:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Center(child:Text('I am JSPang')),
Expanded(child:Center(child:Text('my website is jspang.com'))),
Center(child:Text('I love coding'))
],
)
三.Stack 层叠布局
1. 层叠布局的 alignment 属性
alignment 属性是控制层叠的位置的,建议在两个内容进行层叠时使用。它有两个值 X 轴距离和 Y 轴距离,值是从 0 到 1 的,都是从上层容器的左上角开始算起的
2.CircleAvatar 组件的使用
CircleAvatar 这个经常用来作头像的,组件里边有个 radius 的值可以设置图片的弧度
new CircleAvatar(backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
radius: 100.0,
)
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
var stack = new Stack(alignment: const FractionalOffset(0, 0.1),
children: <Widget>[
new CircleAvatar(backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
radius: 100.0,
),
new Container(
decoration: new BoxDecoration(color: Colors.lightBlue,),
padding: EdgeInsets.all(5.0),
child: new Text('JSPang 技术胖'),
)
],
);
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('垂直方向布局'),
),
body:Center(child:stack),
),
);
}
}
四.Stack 的 Positioned 属性
如果是超过两个组件的层叠该如何进行定位那? 这就是我们加今天要学的主角 Positioned 组件了。这个组件也叫做层叠定位组件
Positioned 组件的属性
bottom: 距离层叠组件下边的距离
left:距离层叠组件左边的距离
top:距离层叠组件上边的距离
right:距离层叠组件右边的距离
width: 层叠定位组件的宽度
height: 层叠定位组件的高度
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
var stack = new Stack(
children: <Widget>[
new CircleAvatar(backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
radius: 100.0,
),
new Positioned(
top:10.0,
left:10.0,
child: new Text('JSPang.com'),
),
new Positioned(
bottom:10.0,
right:10.0,
child: new Text('技术胖'),
)
],
);
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('层叠布局'),
),
body:Center(child:stack),
),
);
}
}
五. 卡片组件布局
Flutter 还有一种比较比较酷炫的布局方式: 卡片式布局。这种布局类似 ViewList,但是列表会以物理卡片的形态进行展示
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
var card = new Card(
child: Column(
children: <Widget>[
ListTile(title:new Text('吉林省吉林市昌邑区',style: TextStyle(fontWeight: FontWeight.w500),),
subtitle: new Text('技术胖:1513938888'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),
ListTile(title:new Text('北京市海淀区中国科技大学',style: TextStyle(fontWeight: FontWeight.w500),),
subtitle: new Text('胜宏宇:1513938888'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),
ListTile(title:new Text('河南省濮阳市百姓办公楼',style: TextStyle(fontWeight: FontWeight.w500),),
subtitle: new Text('JSPang:1513938888'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),],
),
);
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(title:new Text('卡片布局'),
),
body:Center(child:card),
),
);
}
}
一般导航组件
1.RaisedButtom 按钮组件
它有两个最基本的属性:
child:可以放入容器,图标,文字。让你构建多彩的按钮。onPressed:点击事件的相应,一般会调用 Navigator 组件
我们在作页面导航时,大量的使用了 RaisedButton 组件,这个组件的使用在实际工作中用的也比较多
2.Navigator.push 和 Navigator.pop
1.Navigator.push:是跳转到下一个页面,它要接受两个参数一个是上下文 context,另一个是要跳转
2.Navigator.pop:是返回到上一个页面,使用时传递一个 context(上下文)参数,使用时要注意的是,你必须是有上级页面的,也就是说上级页面使用了 Navigator.push。
import 'package:flutter/material.dart';
void main(){
runApp(MaterialApp(
title:'导航演示 1',
home:new MyApp()));
}
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return new Scaffold(appBar: AppBar(title:Text('导航页面')),
body:Center(
child:RaisedButton(child:Text('查看商品详情页面'),
onPressed: (){
Navigator.push(context,new MaterialPageRoute(builder:(context) =>new SecondScreen())
);
},
)
)
);
}
}
class SecondScreen extends StatelessWidget{
@override
Widget build(BuildContext context){
return Scaffold(appBar:AppBar(title:Text('技术胖商品详情页')),
body:Center(
child:RaisedButton(child:Text('返回'),
onPressed: (){Navigator.pop(context);
},
))
);
}
}
# Center 组件
import ‘package:flutter/material.dart’;
void main(){
runApp(new Center( //Center 组件
child: Text(
"文本内容",
textDirection: TextDirection.ltr
)
))
}
# 自定义组件
StatelessWidget // 无状态组件
StatefulWidget // 有状态组件
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center( //Center 组件
child: Text(
"文本内容",
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 40.0,
color: Color.fromRGBO(255,0,0,0.5)
)
)
)
}
}
# MaterialApp 和 Scaffold
> MaterialApp 是一个方便的 Widget, 它封装了应用程序实现 Material Desigin 所需要的一些 Widget 一般作为顶层 Widget 组件
### 常用属性
home(主页)
title(标题)
color(颜色)
theme(主题)
routes(路由)
### Scaffold 组件
> Scaffold 是 Material Desigin 布局结构的基本实现
### Scaffold 组件属性
appBar 显示在界面顶部的一个 appBar
body 当前界面所显示的主要 内饰 Widget
drawer 抽屉菜单控件
import ‘package:flutter/material.dart’;
void main(){
runApp(MaterialApp(
title:'导航演示 1',
home:new MyApp(),
theme:ThemeData(primarySwatch: Colors.yellow)
));
}
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context){
return new Scaffold(appBar: AppBar(title:Text('导航页面')),
body:Center(
child:RaisedButton(child:Text('查看商品详情页面'),
onPressed: (){
Navigator.push(context,new MaterialPageRoute(builder:(context) =>new SecondScreen())
);
},
)
)
);
}
}
class SecondScreen extends StatelessWidget{
@override
Widget build(BuildContext context){
return Scaffold(appBar:AppBar(title:Text('技术胖商品详情页')),
body:Center(
child:RaisedButton(child:Text('返回'),
onPressed: (){Navigator.pop(context);
},
))
);
}
}