组件
flutter的一个组件就是一个类
flutter可以分为两种 一种是无状态组件(静态组件) 可以使用stl输出组件结构
另一种是有状态组件(动态组件) 可以使用stf输出组件结构
使用组件时 规定是new +类名() 一般都把new省略
静态组件
一个静态组件必须有一个build方法
class 组件名字 extends StatelessWidget{
@override
Widget build(BuildContext context) {
return null
}
}
动态组件
分为两部分
一部分是处理状态 要重写createState方法 利用这个函数可以管理state 类似vuex 它的返回值类型是下面函数的名字 返回下面的实例(名字+()) 继承StatefulWidgest
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
一个是写结构的(和无状态的一样 把结构写在build方法中) 继承上面的类的名字
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
}
}
MaterialApp
根组件 一般写在最顶层 类似vue中App 里面封装了一些必要的widget
它可以设置title theme home debugShowMaterialGrid
title 是不显示出来的 只是定义了这个属性
debugShowMaterialGrid是定义界面右上角出现的图标 false就不显示这个图标
home相当于渲染一个组件 可以在home后面直接写组件中的内容 也可以引入一个组件 在home后面输入这个组件的名字
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowMaterialGrid:false,
title: 'flutter',
theme: ThemeData(
primarySwatch: Colors.yellow
),
home: Scaffold(
appBar: AppBar(
title: Text('hello flutter'),
),
body: Center(
child: Text('flutter'),
),
),
);
}
}
Scaffold
相当于脚手架 是一个路由页的骨架
里面有appBar body
appBar是用AppBar这个组件
body可以使用所有的组件
Scaffold(
appBar: AppBar(
title: Text('hello flutter'),
),
body: Center(
child: Text('flutter'),
),
AppBar
导航栏组件 它可以定义 title actions leading centerTitle(标题的对齐方式)
leading中可以放一个图片 也可以放一个icon
title:这个title是现实在导航栏上
actions:是按钮的点击动作
centerTitle是头部导航标题是不是处于居中 true为居中
backgroundColor 头部导航的背景颜色
bottomNavigationBar:底部导航 是使用BottomNavigationBar
drawer:左侧抽屉式导航 是使用Drawer
AppBar(
leading: Icon(Icons.search),
centerTitle:true,
title: Text('hello flutter'),
actions: <Widget>[
IconButton(
onPressed: (){},
icon: Icon(Icons.add),
),
backgroundColor:Colors.red,
],
),
body: Center(
child: Text('flutter'),
),
bottomNavigationBar: BottomNavigationBar(
items: const<BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('首页')
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text('搜索')
),
BottomNavigationBarItem(
icon: Icon(Icons.add),
title: Text('设置')
),
],
),
),
BottomNavigationBar
currentIndex:指定当前的索引 指定好之后 就会出现不一样的样式(一个按钮被选中的样式)
type:BottomNavigationBarType.fixed 如果底部按钮有超过3个时 使用这行就可以实现多个
onTap:点击下面的图标要执行的事情 是一个方法
backgroundColor 背景颜色
selectedItemColor 被选中后的背景颜色
unselectedItemColor 没有被选中的背景颜色
iconSize 组件的大小
items:用来放下面的控件 例如微信下面的 我的 发现 通讯录 是用BottomNavigationBarItem这个存放
int _current = 1;
void _onItemTapped(){
setState((int index) {
_current = index;
});
}
bottomNavigationBar: BottomNavigationBar(
type:BottomNavigationBarType.fixed
current:_current;
onTap: _onItemTapped;
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem
里面有 icon title
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
Drawer
drawer: Drawer(
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
child: Icon(Icons.home),
),
title: Text('我的'),
),
Text
用于显示简单样式文本,它包含一些控制文本显示样式的一些属性
可以直接放文本
Text('文本')
style(用来设置文本的样式) 是使用TextStyle类
Text(
style:TextStyle()
)
overFlow 用来设置文本溢出时,如果有多余的文本,可以通过overflow来指定截断方式,默认是直接截断,本例中指定的截断方式TextOverflow.ellipsis,它会将多余文本截断后以省略符“...”表示;
Text(
overFlow:TextOverFlow.ellipsis
)
textAlign 文本的对齐方式 是用TextAlign
Text(
textAlign:TextAlign.center
)
maxLines 文本最多占用多少行,指定文本显示的最大行数,默认情况下,文本是自动折行的,如果指定此参数,则文本最多不会超过指定的行。
Text(
maxLines:1 //只能占一行
)
textScaleFactor 放大字体
Text(
textScaleFactor:2
)
TextStyle
设置文本的样式 如颜色、字体、粗细、背景等
color 可以使用Color 也可以使用Colors进行设置
style:TextStyle(
color:Colors.red,
color:Color.fromRGBO(r, g, b, opacity)
)
fontSize 设置文本的大小 是一个固定的值
style:TextStyle(
fontSize:40
)
fontWeight 设置文本的粗细 使用FontWeight
style:TextStyle(
fontWeight:FontWeight.w800 //数字可以变
)
fontFamily 设置文本字体
style:TextStyle(
fontFamily:'Courier'
)
decoration 文本的装饰器 decorationColor 修饰线的颜色 decorationStyle修饰线的类型
style:TextStyle(
decoration:TextDecoration.lineThrough,
decorationColor:Colors.red,
decorationStyle:TextDecorationStyle.dashed
)
letterSpacing 字母之间的间距
style:TextStyle(
letterSpacing:2
)
Image
设置图片 图片分为网络的图片和本地的图片
网络图片
Image(
image:NetworkImage('图片的路径'),
width:200,
)
Image.network('图片的路径',width:200)
本地图片
在根路径创建一个image文件夹 用来放图片
在pbspec.yaml中的flutter添上
assets:
- images/avatar.png
注意: 由于 yaml 文件对缩进严格,所以必须严格按照每一层两个空格的方式进行缩进,此处assets前面应有两个空格
使用该图片也有两种方式 1.
Image(
image:AssetImage('images/avatar.png')
)
Image.asset('images/avatar.png')
设置图片
width height
fit(缩放模式)
Image(
fit:BoxFit.fill
)
repeat(重复方式) 默认是不重复的 使用ImageRepeat
Image(
repeat:ImageRepeat.repeat //重复
)
alignment(对齐方式)
Image(
alignment:AlignMent.center
)
Container
相当于html中的div
可以设置 width height
decoration 使用BoxDecoration
Container(
width:100,
height:100,
decoration:BoxDecoration(
color:Colors.red,
border:Border.all(
width:2,
color:Colors.green
),
borderRadius: BorderRadius.all(
Radius.circular(10)
)
)
)
padding margin allignment
Container(
padding: EdgeInsets.all(20),
padding: EdgeInsets.fromLTRB(10, 20, 30, 40),
margin: EdgeInsets.all(20),
alignment: Alignment.bottomRight,
)
BoxDecoration
image div中的图片 类似于背景颜色 使用Image.network() 或者 Image.asset()
color div的颜色 使用Colors.颜色名或者Color.fromRGBA(0,0,0,0)
border div的边框 使用Border.all(width:) Border(top:BorderSide(width:))
borderRadius div边框的圆度 使用BorderRadius.circular(10)
按钮组件
RaisedButton
普通的按钮
color:这个按钮的颜色
textColor:按钮中的文本的颜色
Text:设置按钮中的文字
elevation:设置按钮的阴影
onPressed(){} 设置点击按钮发生的事情
textTheme:设置按钮的主题 使用ButtonTextTheme来进行设置 它还必须和color一起设置时才有效果 这个color和平常设置的不一样 看下面的案例
shape:设置按钮的形状
RaisedButton(
child:Text('按钮'),
color:Colors.blue,
textColor:Colors.white,
elevation:10
)
自定义按钮
设置自定义按钮时 需要外面包一个container 这样就可以设置按钮的大小
Container(
width:100,
height:60,
RaisedButton(
child:Text('按钮'),
color:Colors.blue,
textColor:Colors.white
)
)
如果想设置一个自适应的按钮(宽度占满在整个屏幕),就在外面再设置一个Expanded
圆角按钮
ResiedButton(
shape:RoundedRectangleBorder(
borderRadius:BorderRadius.circular(10)
)
)
圆形按钮
设置圆形按钮时 最好外面包一个Container 这样可以设置高度和宽度
Container(
height:60,
child:ResiedButton(
shape:CircleBorder(
side:BorderSide(color:Colors.blue)
//设置圆形按钮的边框 不设置这个时 也会出现一个圆形按钮
)
)
)
带主题的按钮
RaisedButton(
theme:ButtonTheme.primary,
color:Theme.of(context).accentColor
)
Row
mainAxisAlignment:MainAxisAlignment.center
Column
mainAxisAlignment:MainAxisAlignment.center
SizeBox
SizeBox(width:10)
SizeBox(height:10)
弹出框
提示信息框
AlterDialog()
void _alertDialog() async {
var result = await showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return AlertDialog(
title: Text('提示信息'),
content: Text('你确定删除吗'),
actions: <Widget>[
FlatButton(
child: Text('取消'),
onPressed: () {
print('取消');
Navigator.pop(context, 'cancel');
},
),
FlatButton(
child: Text('确定'),
onPressed: () {
print('确定');
Navigator.pop(context, 'ok');
},
)
],
);
});
}
SimpleDialog 点击这个弹出框的底部和这个界面的底部一致
void _simpleDialog() async {
var result = await showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return SimpleDialog(
title: Text('选择内容'),
children: <Widget>[
SimpleDialogOption(
child: Text('选择A'),
onPressed: () {
Navigator.pop(context, 'A');
},
),
Divider(),
SimpleDialogOption(
child: Text('选择B'),
onPressed: () {
Navigator.pop(context, 'B');
},
)
],
);
});
}
还有第三方的 可以百度pub.dev 搜索
Divider()
是用来加一条横线
Stack()
用来实现定位的 在这里的第一个Container()相当于Stack 后面的都是依据第一个进行定位 里面可以放children alignment
// Stack坐标轴的原点第一个容器中心点
return Stack(
// alignment: Alignment(.5, .5),
// alignment: Alignment(0, 0),
alignment: Alignment(1, 1),
// alignment: Alignment.bottomLeft,
// alignment: Alignment.centerLeft,
children: <Widget>[
Container(
width: 300,
height: 400,
color: Colors.red,
),
Container(
width: 80,
height: 80,
color: Colors.yellow,
),
// Text("hello"),
// Text("word")
],
);
Wrap
看电视时第几集第几集 wrap就是把把他们包括起来
return Scaffold(
appBar: AppBar(title: Text('wrap组件'),),
body: Wrap(
spacing: 10,
children: <Widget>[
RaisedButton(
child: Text('第1集'),
onPressed: (){},
),
RaisedButton(
child: Text('第1集'),
onPressed: (){},
),
RaisedButton(
child: Text('第1集'),
onPressed: (){},
),
RaisedButton(
child: Text('第1集'),
onPressed: (){},
),
RaisedButton(
child: Text('第1集'),
onPressed: (){},
),
RaisedButton(
child: Text('第1集'),
onPressed: (){},
),
RaisedButton(
child: Text('第1集'),
onPressed: (){},
),
],
),
);