一、先写一个小Demo
1.Scaffold这个Widget,使用在MaterialApp中,包含了页面中常用的一些控件,如AppBar
,NavigationBar等。如果要显示,在Scaffold添加相应的Key-Value值即可,如appBar:new AppBar(title:Text('AppBar'))
2.设置App主题颜色,在MaterialApp中添加theme属性即可,在其Value中设置颜色。如:
class App extends StatelessWidget{
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: Scaffold(
//显示AppBar
appBar: new AppBar(
title: Text('第一个FlutterApp'),
elevation: 0.0,
),
body: Hello(),
),
theme: ThemeData(
primarySwatch: Colors.yellow //设置主题颜色
)
);
}
}
3.Container这个Widget,可以用来作为一个小布局,里面可以设置子控件的摆放位置。在使用ListView.builder创建列表时,第一个属性itemCount表示列表大小,第二个itemBuilder是用来创建每一个列表视图的。Column表示纵向列表。
class Home extends StatelessWidget{
Widget _ListitemBuider(BuildContext context,int index){
return Container(
color: Colors.white,//背景颜色
margin: EdgeInsets.all(8.0),//设置Maigin
//child:Container内容 Column:纵向排列
child: Column(
children: <Widget>[
Image.network(posts[index].imageUrl),
SizedBox(height: 16.0,),//可以用作间隔
Text(
posts[index].title,
style: Theme.of(context).textTheme.title,
),
SizedBox(height: 16.0,),
Text(
posts[index].author,
style: Theme.of(context).textTheme.subhead,
),
],
),
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
//Scaffold 包含了布局中常用的一些
home: Scaffold(
backgroundColor: Colors.grey[100],
appBar: new AppBar(
title: Text('第一个FlutterApp'),
elevation: 0.0,
),
body: ListView.builder(
itemCount: posts.length,
itemBuilder: _ListitemBuider),
),
theme: ThemeData(
primarySwatch: Colors.yellow
)
);
}
}
4.不显示App顶部debug条幅:在MaterialApp中设置属性debugShowCheckedModeBanner: false
5.在AppBar左侧和右侧添加内容:
appBar: new AppBar(
//设置AppBar左侧图标
leading: IconButton(
icon: Icon(Icons.menu),
tooltip: 'Navigation',
onPressed: () => debugPrint('Navigation Button is pressed')),
title: Text('第一个FlutterApp'),
elevation: 0.0,
//设置AppBar右侧图标
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: () => debugPrint('Search Button is pressed'),
),
],
),
右侧是一个 ‘action:<Widget>[....]’ 集合,右侧可以添加多个图标
6.使用Tab。
Flutter中的一套Tab包括:Tab、TabBar、TabView、TabController。在AppBar的底部设置TabBar,在TabBar中设置tabs属性,在tabs中设置一个个的Tab。在body中设置TabBarView,其中也是<Widget>[]集合,集合中显示的是页面主体内容,相当于ViewPager中的Pager。需要注意的是,这里设置Tab上面label和indicator的几行代码:分别是unselectedLabelColor:未选中时label的颜色;indicatorColor:indicator的颜色;indicatorSize:indicator的宽度;indicatorWeight:indicator的宽度
代码如下:
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
//TabController,将TabBar和TabView联系起来
return DefaultTabController(
length: 3,//设置Tab的数量
child: Scaffold(
backgroundColor: Colors.grey[100],//甚至Scaffold的背景颜色
appBar: new AppBar(
//设置AppBar左侧图标
leading: IconButton(
icon: Icon(Icons.menu),
tooltip: 'Navigation',
onPressed: () => debugPrint('Navigation Button is pressed')),
title: Text('第一个FlutterApp'),
elevation: 0.0,
//设置AppBar右侧图标
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: () => debugPrint('Search Button is pressed'),
),
],
//在AppBar的bottom部分设置TabBar
bottom: TabBar(
//设置TabBar的样式
unselectedLabelColor: Colors.black38,
indicatorColor: Colors.black38,
indicatorSize: TabBarIndicatorSize.label,//与Tab中的图标一样宽,
indicatorWeight: 3.0,//(在垂直方向上indicator的weight)indicator宽度
//设置TabBar内容
tabs: <Widget>[
Tab(icon: Icon(Icons.local_activity),),
Tab(icon: Icon(Icons.local_airport),),
Tab(icon: Icon(Icons.local_atm),)
]),
),
body:TabBarView(
//设置TabBarView
children: <Widget>[
Icon(Icons.local_activity,size: 128.0,color: Colors.black12,),
Icon(Icons.local_airport,size: 128.0,color: Colors.black12,),
Icon(Icons.local_atm,size: 128.0,color: Colors.black12,)
]),
));
}
}
7.设置高亮颜色,即控件被选中时的背景色:在MatrialApp的Theme属性中设置: highlightColor: Color.fromRGBO(255, 255, 255, 0.5),设置水波纹颜色 splashColor: Colors.white70//设置水波纹颜色
class App extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Home(),
theme: ThemeData(
primarySwatch: Colors.yellow,
highlightColor: Color.fromRGBO(255, 255, 255, 0.5),//设置高亮颜色
splashColor: Colors.white70//设置水波纹颜色
),
);
}
}
8.使用Drawer
在Scaffold中,添加drawer属性。
1.如果要自定义Drawer的内容,使用Container这个Widget
drawer: Container(
color: Colors.white,//背景颜色
padding: EdgeInsets.all(8.0),//padding
child: Column(
mainAxisAlignment: MainAxisAlignment.center,//与中线对齐
children: <Widget>[
Text('This is a drawer'),
SizedBox(height: 10.0,),
Text('This is a drawer'),
SizedBox(height: 10.0,)
],
),
),
2.使用官方的Drawer这个Widget。
头部:DrawerHeader,身体:使用ListTile
drawer:Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Header'.toUpperCase()),//大写
//设置背景颜色
decoration:BoxDecoration(
color: Colors.grey[100]
),
),
ListTile(
title: Text('Message',textAlign: TextAlign.left,),
//在文字右侧显示图标
// trailing: Icon(Icons.message,color: Colors.black12,size: 22.0,),
//在文字左侧显示图标
leading: Icon(Icons.message,color: Colors.black12,size: 22.0),
onTap: () => Navigator.pop(context),
),
ListTile(
title: Text('Message',textAlign: TextAlign.left,),
//在文字右侧显示图标
// trailing: Icon(Icons.message,color: Colors.black12,size: 22.0,),
//在文字左侧显示图标
leading: Icon(Icons.message,color: Colors.black12,size: 22.0),
onTap: () => Navigator.pop(context),
),
ListTile(
title: Text('Message',textAlign: TextAlign.left,),
//在文字右侧显示图标
// trailing: Icon(Icons.message,color: Colors.black12,size: 22.0,),
//在文字左侧显示图标
leading: Icon(Icons.message,color: Colors.black12,size: 22.0),
onTap: () => Navigator.pop(context),
),
],
),
)
3.使用Api提供的UserAccountsDrawerHeader
Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text('KimLiu'),//用户名称
accountEmail: Text('safan@126.com'),//用户邮箱
currentAccountPicture: CircleAvatar(
backgroundImage: NetworkImage('https://resources.ninghao.org/images/tornado.jpg'),
),//头像
//设置背景颜色等属性
decoration: BoxDecoration(
color: Colors.yellow[400],
image: DecorationImage(
image: NetworkImage('https://resources.ninghao.org/images/tornado.jpg'),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.yellow[400].withOpacity(0.6),//设置不透明度
BlendMode.hardLight)
)
),)
,
ListTile(
title: Text('Message',textAlign: TextAlign.left,),
//在文字右侧显示图标
// trailing: Icon(Icons.message,color: Colors.black12,size: 22.0,),
//在文字左侧显示图标
leading: Icon(Icons.message,color: Colors.black12,size: 22.0),
onTap: () => Navigator.pop(context),
),
ListTile(
title: Text('Message',textAlign: TextAlign.left,),
//在文字右侧显示图标
// trailing: Icon(Icons.message,color: Colors.black12,size: 22.0,),
//在文字左侧显示图标
leading: Icon(Icons.message,color: Colors.black12,size: 22.0),
onTap: () => Navigator.pop(context),
),
ListTile(
title: Text('Message',textAlign: TextAlign.left,),
//在文字右侧显示图标
// trailing: Icon(Icons.message,color: Colors.black12,size: 22.0,),
//在文字左侧显示图标
leading: Icon(Icons.message,color: Colors.black12,size: 22.0),
onTap: () => Navigator.pop(context),
),
],
),
);
9.添加底部导航栏
在Scaffold中使用bottomNavigationBar。
bottomNavigationBar: BottomNavigationBar(
currentIndex: 1,//当前被激活的item索引值
type: BottomNavigationBarType.fixed,//当底部导航栏个数超过4个时,需要设置这个属性,才会显示
fixedColor: Colors.black,//Item激活状态下的颜色
items: [
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today),
title: Text('打卡')),
BottomNavigationBarItem(
icon: Icon(Icons.receipt),
title: Text('上报')),
BottomNavigationBarItem(
icon: Icon(Icons.list),
title: Text('列表')),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text('我的')),
]),
点击时,切换Item的选中状态。这里要用到setState(),因此,创建一个BottomNavigationDemo继承StatefulWidget,改变currentIndex的值。
class BottomNavigationDemo extends StatefulWidget{
@override
_BottomNavigationState createState() {
// TODO: implement createState
return new _BottomNavigationState();
}
}
class _BottomNavigationState extends State<BottomNavigationDemo>{
int _currentIndex = 0;
void _onTabHandler(int index){
setState(() {
_currentIndex = index;
});
}
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: _currentIndex,//当前被激活的item索引值
type: BottomNavigationBarType.fixed,//当底部导航栏个数超过4个时,需要设置这个属性,才会显示
fixedColor: Colors.black, //Item激活状态下的颜色
onTap: _onTabHandler,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today),
title: Text('打卡')),
BottomNavigationBarItem(
icon: Icon(Icons.receipt),
title: Text('上报')),
BottomNavigationBarItem(
icon: Icon(Icons.list),
title: Text('列表')),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text('我的')),
]);
}
}
二、基础部件
基础部件的各种属性,可查看Api文档:https://flutterchina.club/widgets/
1.Text
class BasicDemo extends StatelessWidget{
final TextStyle _textStyle = TextStyle(
fontSize: 16.0
);
final String _author = '李白';
final String _title = '将进酒';
@override
Widget build(BuildContext context) {
// TODO: implement build
return Text(
//使用title 和 author这两个变量
'《$_title》--- $_author 。 君不见黄河之水天上来,奔流到海不复回。君不见高堂明镜悲白发,朝如青丝暮成雪。'
'人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。',
textAlign: TextAlign.center,
style: _textStyle,//抽离出TextStyle
maxLines: 3,
overflow: TextOverflow.ellipsis,);
}
}
2.RichText 一行文字显示多种样式
RichText(
text: TextSpan(
text:'KimLiu',
style: TextStyle(
color: Colors.deepPurpleAccent,
fontSize:34.0,
fontStyle: FontStyle.italic,//斜体
fontWeight: FontWeight.w100
),
//如果要设置不同样式的字体
children: [
TextSpan(
text: 'dalao',
style: TextStyle(
fontSize: 17.0,
color: Colors.blueGrey
)
)
]
),
);
3.Container 容器 alignment:容器中的控件,对齐的方式。
Container(
// color: Colors.grey[100], //容器背景颜色,也可以用decoration: BoxDecoration(),
decoration: BoxDecoration(
//设置背景图片
image: DecorationImage(
image: NetworkImage('https://resources.ninghao.org/images/tornado.jpg'),
alignment: Alignment.topCenter,//控制图片位置
// repeat: ImageRepeat.repeatY,//设置图片是否重复
fit: BoxFit.cover,
//设置颜色滤镜 (颜色,混合模式)
colorFilter: ColorFilter.mode(
Colors.indigoAccent[400].withOpacity(0.5),//设置不透明度
BlendMode.hardLight),
)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,//居中显示
children: <Widget>[
Container(
// alignment: Alignment(0.0, 0.0),//icon在正中间
// alignment: Alignment(1.0, 0.0),//icon在最右边
// alignment: Alignment(-1.0, 0.0),//icon在最左边
// alignment: Alignment(0.0, 1.0),//icon在最下面
// alignment: Alignment(0.0, -1.0),//icon在最上面
alignment: Alignment.topCenter,//对齐方式
child: Icon(Icons.pool,size: 32.0,color: Colors.white),
//设置背景颜色 也可以使用decoration: BoxDecoration(),
// color: Color.fromRGBO(3, 54, 255, 1.0),
decoration: BoxDecoration(
color: Color.fromRGBO(3, 54, 255, 1.0),
//统一设置边框的颜色、宽度、样式
border: Border.all(
color: Colors.indigoAccent[100],//边框的颜色
width: 3.0,//边框的宽度
style: BorderStyle.solid
),
// borderRadius: BorderRadius.circular(16.0),//设置圆角值
//阴影效果 是一组值,可根据需要去设置
boxShadow: [
BoxShadow(
offset: Offset(6.0,7.0), //偏移量 参数1 :X轴偏移量 参数2:Y轴偏移量
color: Color.fromRGBO(16, 20, 188, 1.0),//阴影颜色
blurRadius: 20.0,//模糊程度半径
spreadRadius: 6.0//阴阳扩散的程度,可以是正数,也可以是负数(缩小阴影)
),
],
shape: BoxShape.circle,//改变盒子形状 BoxShape.circle不能同borderRadius一起使用
//渐变
gradient: LinearGradient(
colors: [
Colors.indigoAccent,
Colors.red
],
begin: Alignment.topCenter, //渐变开始的位置
end: Alignment.bottomCenter,//渐变结束的位置
),
// //分别设置4个边的边框颜色、宽度、样式等
// border: Border(
// top: BorderSide(
// color: Colors.indigoAccent[100],//边框的颜色
// width: 3.0,//边框的宽度
// style: BorderStyle.solid
// ),
// bottom: BorderSide(
// color: Colors.indigoAccent[100],//边框的颜色
// width: 3.0,//边框的宽度
// style: BorderStyle.solid
// )
),
//设置padding only表示可以分别设置4边的属性
// padding: EdgeInsets.only(left: 10.0,top: 20.0,right: 30.0,bottom: 40.0),
padding: EdgeInsets.all(16.0),
margin: EdgeInsets.all(8.0),
width: 90.0,//宽
height: 90.0,//高
)
],
),
);
4.Row和Column
Row:行;Column:列,两者的用法差不多一样。其中 mainAxisAlignment 属性是 主轴,crossAxisAlignment:是与主轴垂直的线,被取名为交叉轴。
Row(
//主轴
// mainAxisAlignment: MainAxisAlignment.spaceAround,//主轴上剩下的空间分配到小部件的周围
// mainAxisAlignment: MainAxisAlignment.spaceBetween,//主轴上剩下的空间会分配到小部件之间
mainAxisAlignment: MainAxisAlignment.spaceEvenly,//主轴上剩下的空间平均的分配到小部件之间
//交叉轴 :与主轴垂直的线
// crossAxisAlignment: CrossAxisAlignment.start, //交叉轴顶部对齐
crossAxisAlignment: CrossAxisAlignment.stretch,//拉伸
children: <Widget>[
IconBadge(Icons.pool,size: 64.0,),
IconBadge(Icons.access_time,size:64.0),
],
);
5.SizeBox:一般用于设置两个控件之间的间隔,也可以在其中添加装饰decoration。
Row(
children: <Widget>[
SizedBox(
width: 100.0,
height: 100.0,
child: Container(
//装饰
decoration: BoxDecoration(
color: Color.fromRGBO(3, 54, 255, 1.0),
borderRadius: BorderRadius.circular(8.0),//圆角效果
) ,
child: Icon(Icons.ac_unit,color: Colors.white,size: 32.0,),
),
),
//上下两个控件之间的间隔
SizedBox(
width: 32.0,
),
SizedBox(
width: 100.0,
height: 100.0,
child: Container(
//装饰
decoration: BoxDecoration(
color: Color.fromRGBO(3, 54, 255, 1.0),
borderRadius: BorderRadius.circular(8.0),//圆角效果
) ,
child: Icon(Icons.ac_unit,color: Colors.white,size: 32.0,),
),)
],
);
6.Stack:一摞小部件
Stack(
children: <Widget>[
SizedBox(
width: 50,
height: 50,
child: Container(
// alignment: Alignment(0.0, 0.0),//icon在正中间
// alignment: Alignment(1.0, 0.0),//icon在最右边
// alignment: Alignment(-1.0, 0.0),//icon在最左边
// alignment: Alignment(0.0, 1.0),//icon在最下面
// alignment: Alignment(0.0, -1.0),//icon在最上面
alignment: Alignment.topCenter,//对齐方式
//装饰
decoration: BoxDecoration(
color: Color.fromRGBO(3, 54, 255, 1.0),
borderRadius: BorderRadius.circular(8.0),//圆角效果
) ,
child: Icon(Icons.ac_unit,color: Colors.white,size: 32.0,),
),
),
//上下两个控件之间的间隔
SizedBox(
width: 32.0,
),
SizedBox(
width: 100.0,
height: 100.0,
child: Container(
//装饰
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
color: Color.fromRGBO(3, 54, 255, 1.0),
borderRadius: BorderRadius.circular(8.0),//圆角效果
) ,
child: Icon(Icons.access_time,color: Colors.white,size: 32.0,),
),
),
// 可以确定位置的小部件
Positioned(
right: 20,//距右侧20
child: Icon(Icons.access_alarms,color: Colors.white,size: 32.0,),
)
],)
7.AspectRatio:可设置宽高比的控件
AspectRatio(
aspectRatio: 3.0/2.0,//得到一个宽高比是3/2的容器
child: Container(
color: Colors.blue,
),
)
8.ConstrainedBox:点限制的盒子
ConstrainedBox(
//对盒子的限制在这里设置
constraints: BoxConstraints(
minWidth: 200.0,
maxHeight: 200.0
),
child: Container(
color: Colors.blue,
),)