我在之前的文章文本、图片和按钮在Flutter中怎么用中,简单介绍过按钮组件,本篇文章来详细聊聊Flutter中的各种按钮组件的各种应用场景。
在Flutter中,有很多的按钮组件,常见的有:FlatButton、RaisedButton、OutlineButton、IconButton、ButtonBar、FloatingActionButton等。本文我将对其中的某几类做详细讲解。
FlatButton、RaisedButton、OutlineButton
实际上,FlatButton、RaisedButton和OutlineButton这三个按钮组件的内部属性基本都是一样的,所以我接下来以RaisedButton为例来详细介绍一下这三类按钮组件该怎么去使用。
首先来看一下按钮组件的属性:
下面是代码实例:
Column(
mainAxisAlignment: MainAxisAlignment.center, //竖直方向上居中
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center, //水平方向上居中
children: <Widget>[
RaisedButton(
child: Text("普通按钮"),
onPressed: () => print("普通按钮"),
),
SizedBox(width: 10), //间隔
RaisedButton(
child: Text("有颜色按钮"),
onPressed: () => print("有颜色按钮"),
color: Colors.blue,
textColor: Colors.white,
),
SizedBox(width: 10),
RaisedButton(
child: Text("有阴影按钮"),
onPressed: () => print("有阴影按钮"),
elevation: 30,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
height: 50,
child: RaisedButton(
child: Text("自定义按钮的宽高"),
onPressed: () => print("自定义按钮的宽高"),
),
),
SizedBox(width: 10),
RaisedButton.icon(
icon: Icon(Icons.search),
label: Text("带图标按钮"),
onPressed: () => print("图标按钮"),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
//自适应布局
child: Container(
margin: EdgeInsets.all(10), //外边距
height: 60,
child: RaisedButton(
child: Text("自适应按钮 & 设置水波纹颜色"),
onPressed: () => print("自适应按钮"),
splashColor: Colors.pink,
),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text("圆角按钮"),
onPressed: () => print("圆角按钮"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10) //设置圆角
),
),
SizedBox(width: 10),
Container(
width: 100,
height: 100,
child: RaisedButton(
child: Text("圆形按钮"),
onPressed: () => print("圆形按钮"),
shape: CircleBorder(
//设置圆形
side: BorderSide(
color: Colors.white, //设置圆形的边框色
)),
),
)
],
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text("按钮的禁用状态"),
onPressed: null,//通过将onPressed设置为null来实现按钮的禁用状态
color: Colors.pink,
disabledColor: Colors.grey,
)
],
)
],
);
效果如下:
上述例子我都是以RaisedButton为例来演示的,实际上,RaisedButton、FlatButton和OutlineButton这三者的使用都是完全一样的。接下来我就来比较一下这三者的展示效果。
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.blue,
child: Text("RaisedButton"),
onPressed: ()=>print("RaisedButton"),
),
],
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
color: Colors.blue,
child: Text("FlatButton"),
onPressed: ()=>print("FlatButton"),
),
],
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
OutlineButton(
color: Colors.blue,//给OutlineButton设置背景颜色是没有用的
child: Text("OutlineButton"),
onPressed: ()=>print("OutlineButton"),
),
],
)
],
)
效果如下:
实际上,RaisedButton是立体效果的,而FlatButton是扁平化的平面效果;OutlineButton是边框按钮,对齐设置背景颜色是不起效果的。
IconButton、ButtonBar、自定义按钮组件
IconButton这个组件一般是用在定义顶部导航栏上的按钮:
appBar: AppBar(
centerTitle: true,
title: Text("用户中心"),
//定义顶部导航栏的左侧按钮
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () => print("menu"),
),
//定义顶部导航栏的右侧按钮组
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () => print("search"),
),
IconButton(
icon: Icon(Icons.edit),
onPressed: () => print("edit"),
)
],
)
效果如下:
ButtonBar是一个按钮组,也就是说将多个按钮组合在一起。
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ButtonBar(
children: <Widget>[
RaisedButton(
color: Colors.blue,
child: Text("登录"),
onPressed: () => print("登录"),
),
OutlineButton(
child: Text("注册"),
onPressed: () => print("注册"),
),
],
)
],
)
],
)
效果如下:
好,到现在为止,我们了解了RaisedButton、FlatButton、OutlineButton、IconButton和ButtonBar,还有一个FloatingActionButton我们会在下面单独开一个小节去讲,现在我们先来聊聊如何去自定义一个Button组件。
在做项目开发的时候,我们可能会一些风格统一、但需要写很多代码才能实现出来的按钮组件,这个时候我们就可以自己去定义实现一个组件,用来简化代码。
//使用自定义的按钮
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//使用自定义的按钮
CustomButton(
width: 200,
btnTitle: "自定义按钮",
onPressed: ()=>print("自定义按钮"),
)
],
)
],
)
//自定义按钮
class CustomButton extends StatelessWidget {
const CustomButton(
{Key key,
this.btnTitle = "",
this.onPressed = null,
this.width = 100,
this.height = 100})
: super(key: key);
final String btnTitle; //按钮标题
final onPressed; //按钮点击回调
final double width; //按钮的宽度
final double height; //按钮的高度
@override
Widget build(BuildContext context) {
return Container(
height: height,
width: width,
child: RaisedButton(
child: Text(btnTitle),
onPressed: onPressed,
),
);
}
}
其效果如下:
FloatingActionButton
FloatingActionButton简称FAB,可以实现浮动按钮,也可以实现类似闲鱼APP的底部凸起导航:
FloatingActionButton有如下属性:
首先我们先在一个普通页面展示一下FloatingActionButton的效果,代码如下所示:
Scaffold(
//悬浮按钮
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.black,//图标的颜色
size: 20,//图标大小
),
onPressed: () => print("FloatingActionButton"),
backgroundColor: Colors.yellow, //按钮的背景颜色
),
//配置悬浮按钮的位置
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
appBar: AppBar(
...
),
body: Column(
...
),
);
效果如下:
关于上述代码,有以下几点需要说明:
1,是给 Scaffold 组件的 floatingActionButton 属性配置悬浮按钮组件FloatingActionButton
2,通过 Scaffold 组件的 floatingActionButtonLocation 属性,我们可以配置浮动组件的位置
3,floatingActionButton 和 floatingActionButtonLocation 都是 Scaffold 组件的属性,与 appBar 属性同级。
4,floatingActionButton的 child 属性,我们一般是给其配置成Icon,不建议给其配置成其他组件。
接下来,我们来聊一聊如何实现闲鱼底部Tabbar上的凸起按钮的效果。
首先来看代码:
class TabsPage extends StatefulWidget {
TabsPage({Key key}) : super(key: key);
_TabsPageState createState() => _TabsPageState();
}
class _TabsPageState extends State<TabsPage> {
int _tabbarIndex = 0;
List _tabPages = [HomePage(), CategoryPage(), SettingPage()];
@override
Widget build(BuildContext context) {
return Scaffold(
//左侧侧边栏
drawer: Drawer(
......
),
//右侧侧边栏
endDrawer: Drawer(
child: Text("右侧侧边栏"),
),
//floatingActionButton
floatingActionButton: Container(
width: 80,
height: 80,
padding: EdgeInsets.all(8),
margin: EdgeInsets.only(top: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
color: Colors.white,
),
child: FloatingActionButton(
backgroundColor: this._tabbarIndex==1 ? Colors.red : Colors.yellow,
child: Icon(Icons.add),
onPressed: () {
print("floatingActionButton");
setState(() {
this._tabbarIndex = 1;
});
},
),
),
//配置悬浮按钮的定位
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
title: Text("DrawerDemo"),
),
body: _tabPages[_tabbarIndex],
bottomNavigationBar: BottomNavigationBar(
iconSize: 36,
currentIndex: _tabbarIndex,
fixedColor: Colors.pink,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
BottomNavigationBarItem(
icon: Icon(Icons.category), title: Text("分类")),
BottomNavigationBarItem(
icon: Icon(Icons.settings), title: Text("设置")),
],
onTap: (index) {
setState(() {
this._tabbarIndex = index;
});
},
),
);
}
}
效果如下:
关于上述代码,有以下几点需要注意:
1,我们需要在带有底部导航的Scaffold里面配置悬浮按钮。
2,通过配置Scaffold组件的 floatingActionButtonLocation 属性来去确定悬浮按钮的定位。
3,如果我们想要修改悬浮按钮的尺寸大小,可以在其外层包一个Container组件。
4,可以通过配置Container的圆角和内边距,来实现悬浮按钮外层的白色不透明圆边的效果。
5,通过配置Container的外边距margin来调整悬浮按钮的位置。有些时候悬浮按钮不能将底部Tabbar上处于中间位置的item图标完全覆盖,此时我们就通过设置外边距来调整悬浮按钮的位置(主要是上下调整)。
6,在点击悬浮按钮的时候,我们可以通过调整 _tabbarIndex 的值来切换页面。
7,通过一个三目运算符来实现悬浮按钮选中与否的颜色(配置FloatingActionButton的backgroundColor属性)切换:
backgroundColor: this._tabbarIndex==1 ? Colors.red : Colors.yellow,
以上。