版權(quán)聲明:本文為作者原創(chuàng)書籍授嘀。轉(zhuǎn)載請注明作者和出處,未經(jīng)授權(quán)锣险,嚴禁私自轉(zhuǎn)載粤攒,侵權(quán)必究!4殉帧夯接!
情感語錄:得之坦然,失之淡然纷妆;爭其必然盔几,順其自然!
歡迎來到本章節(jié)掩幢,上一章節(jié)我們講了側(cè)邊欄
的使用逊拍,知識點回顧 戳這里 Flutter基礎(chǔ)第七章
本章節(jié)將對Flutter中的按鈕組件進行介紹,在前面章節(jié)的講解中际邻,其實已經(jīng)使用到了一些按鈕組件芯丧,比如 RaisedButton
、IconButton
當(dāng)然在Flutter中可不止這兩個按鈕世曾,本篇會將常用的按鈕組件都進行羅列講解缨恒。
本章簡要:
1、RaisedButton :Material Design 風(fēng)格的凸起按鈕
2轮听、FlatButton :扁平化的按鈕
3骗露、OutlineButton:線框按鈕
4、IconButton :圖標(biāo)按鈕
5血巍、ButtonBar:按鈕組
6萧锉、FloatingActionButton:浮動按鈕
7、自定義實現(xiàn)(左述寡,上柿隙,右叶洞,下)的圖標(biāo)按鈕
8、實戰(zhàn) 閑魚app 底部不規(guī)則按鈕
按鈕組件中的通用屬性:
名稱 屬性值
onPressed 按下按鈕時觸發(fā)的回調(diào)禀崖,接收一個方法衩辟,不填或者傳 null 表示按鈕禁用
child 文本控件
textColor 文本顏色
color 按鈕的顏色
disabledColor 按鈕禁用時的顏色
disabledTextColor 按鈕禁用時的文本顏色
splashColor 點擊按鈕時水波紋的顏色
highlightColor 點擊(長按)按鈕后按鈕的顏色
elevation 陰影的范圍,值越大陰影范圍越大
padding 內(nèi)邊距
shape 設(shè)置按鈕的形狀:
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)
shape: CircleBorder(
side: BorderSide(color: Colors.white)
)
一 帆焕、RaisedButton :
RaisedButton 是 Flutter 提供的 Material 風(fēng)格的按鈕,onPressed
屬性可以傳遞 null 值不恭,如果傳遞了 null 值或者不寫也為null叶雹,整個按鈕是不可點擊的,disabled 狀態(tài)(灰色)
構(gòu)造函數(shù)如下:
const RaisedButton({
Key key,
@required VoidCallback onPressed,
ValueChanged<bool> onHighlightChanged,
ButtonTextTheme textTheme,
Color textColor,
Color disabledTextColor,
Color color,
Color disabledColor,
Color focusColor,
Color hoverColor,
Color highlightColor,
Color splashColor,
Brightness colorBrightness,
double elevation,
double focusElevation,
double hoverElevation,
double highlightElevation,
double disabledElevation,
EdgeInsetsGeometry padding,
ShapeBorder shape,
Clip clipBehavior,
FocusNode focusNode,
MaterialTapTargetSize materialTapTargetSize,
Duration animationDuration,
Widget child,
})
1换吧、普通 Button 及背景顏色控制折晦、陰影控制
import 'package:flutter/material.dart';
class RaisedButtonPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("RaisedButtonPage"),
),
body: Column(
children: <Widget>[
Row(
children: <Widget>[
SizedBox(width: 5),
RaisedButton(
child: Text('無事件按鈕'),
),
SizedBox(width: 5),
RaisedButton(
child: Text('普通按鈕'),
onPressed: () {},
),
SizedBox(width: 5),
RaisedButton(
color: Colors.pink,
textColor: Colors.white,
child: Text('顏色按鈕'),
onPressed: () {},
),
SizedBox(width: 5),
RaisedButton(
elevation: 20,
focusElevation: 40,
child: Text('陰影按鈕'),
onPressed: () {},
),
],
)
],
)
)
);
}
}
效果如下:
2、控制 Button 的寬度和高度
RaisedButton 本身沒有寬度和高度的屬性控制沾瓦,也沒有 margin 屬性可利用满着,如果要指定寬度和高度,可以借助 Container 容器贯莺,設(shè)置 Container 寬度和高度達到控制 RaisedButton 寬高风喇,或者其他能設(shè)置寬高的布局widget也可以,如 :SizedBox
等
Row(
children: <Widget>[
SizedBox(width: 5),
Container(
width: 200,
height: 50,
child: RaisedButton(
child: Text('寬:200,高:50 按鈕'),
onPressed: () {},
),
),
SizedBox(width: 5),
Container(
width: 220,
height: 40,
child: RaisedButton(
color: Colors.pink,
textColor: Colors.white,
child: Text('寬:220,高:40 按鈕'),
onPressed: () {},
),
)
],
)
效果如下:
3缕探、寬度自適應(yīng)按鈕
某些場景下魂莫,我們可能期望一個 Button 充滿整個屏幕寬度。和寬度高度的控制一樣爹耗,我們需要借助 Row + Expanded 耙考,或者使用 無窮值 double.infinity
方式。
Row(
children: <Widget>[
Expanded(
child: Container(
height: 50,
child: RaisedButton(
child: Text('組合控制自適應(yīng)'),
onPressed: () {},
),
),
)
],
),
SizedBox(height: 30),
Container(
width: double.infinity,
height: 40,
child: RaisedButton(
color: Colors.pink,
textColor: Colors.white,
child: Text('無窮寬值方式'),
onPressed: () {},
),
)
效果如下:
4潭兽、圓角 & 圓形 按鈕
RasedButton 圓角可以通過 shape 屬性控制倦始,shape 屬性支持傳入 RoundedRectangleBorder 并且指定 RoundedRectangleBorder.borderRadius 的圓角值實現(xiàn)按鈕圓角。
RaisedButton(
child: Text('圓角按鈕',style: TextStyle(color: Colors.white)),
color: Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
onPressed: () {},
),
效果如下:
RasedButton 圓形可以借助 RaisedButton.shape 來實現(xiàn)山卦,本身 shape 支持傳入的屬性是 ShapeBorder 即可鞋邑,而 CircleBorder 也是繼承自 ShapeBorder。需要注意的是通過這種方式實現(xiàn)圓形按鈕账蓉,當(dāng)內(nèi)部文字過長就會顯示不出來炫狱,需要外部容器包裝下。
SizedBox(
height: 70,
child: RaisedButton(
child: Text('圓形按鈕',style: TextStyle(color: Colors.white)),
color: Colors.green,
shape: CircleBorder(
side: BorderSide(color: Colors.blue),
),
onPressed: () {},
),
),
效果如下:
5剔猿、圖標(biāo)按鈕
造函數(shù) RaisedButton.icon 中可以配置一個帶有圖標(biāo)的按鈕视译。
factory RaisedButton.icon({
Key key,
@required VoidCallback onPressed,
ValueChanged<bool> onHighlightChanged,
ButtonTextTheme textTheme,
Color textColor,
Color disabledTextColor,
Color color,
Color disabledColor,
Color focusColor,
Color hoverColor,
Color highlightColor,
Color splashColor,
Brightness colorBrightness,
double elevation,
double highlightElevation,
double disabledElevation,
ShapeBorder shape,
Clip clipBehavior,
FocusNode focusNode,
MaterialTapTargetSize materialTapTargetSize,
Duration animationDuration,
@required Widget icon,
@required Widget label,
}) = _RaisedButtonWithIcon;
運用下這種方式:
RaisedButton.icon(
color: Colors.pink,
textColor: Colors.white,
icon: Icon(Icons.settings),
label: Text('圖標(biāo)按鈕'),
onPressed: () {},
),
效果如下:
開發(fā)中這種帶有圖標(biāo)的按鈕還是非常常見的,不過很遺憾的事 Flutter 就只給我們提供了圖標(biāo)放在左邊的這種方式归敬,那如果我想實現(xiàn)像Android 原生 TextView
那樣 左酷含,上鄙早,右,下都可以定制一個圖標(biāo)那該怎么辦呢椅亚?
首先我們?nèi)タ聪翭lutter中是怎么實現(xiàn)放置一個 Icon 的限番,跟進 RaisedButton.icon
源碼:
/// The type of of RaisedButtons created with [RaisedButton.icon].
///
/// This class only exists to give RaisedButtons created with [RaisedButton.icon]
/// a distinct class for the sake of [ButtonTheme]. It can not be instantiated.
class _RaisedButtonWithIcon extends RaisedButton with MaterialButtonWithIconMixin {
_RaisedButtonWithIcon({
Key key,
@required VoidCallback onPressed,
ValueChanged<bool> onHighlightChanged,
ButtonTextTheme textTheme,
.....
.....
.....
@required Widget icon,
@required Widget label,
}) : assert(elevation == null || elevation >= 0.0),
assert(highlightElevation == null || highlightElevation >= 0.0),
assert(disabledElevation == null || disabledElevation >= 0.0),
assert(icon != null),
assert(label != null),
super(
key: key,
onPressed: onPressed,
.....
.....
.....
focusNode: focusNode,
materialTapTargetSize: materialTapTargetSize,
animationDuration: animationDuration,
child: Row( // 標(biāo)記1
mainAxisSize: MainAxisSize.min,
children: <Widget>[
icon,
const SizedBox(width: 8.0),
label,
],
),
);
刪掉些無用相關(guān)代碼,(標(biāo)記1)
發(fā)現(xiàn)其實很簡單呀舔,就是定義了個 icon弥虐,然后,把這個 icon和 label用 Row 給包起來了媚赖,按照他這種方式霜瘪,我們也可以去實現(xiàn)其他方位的圖標(biāo)添加了,比如我想實現(xiàn)頂部一個圖標(biāo)的我就用 Column
組件去包裝一個 Icon 和 一個Text 方式 ,如果想實現(xiàn)右邊有個Icon的惧磺,我也用Row
組件去包裝颖对,不過我先放Text 組件 然后在放 Icon組件。
不過每次都要這樣去寫是不是很麻煩啊磨隘,能像原生一樣簡單點嗎缤底? 沒辦法自己擼一個吧,我們先自定義一個類似于Android中支持 android:drawableLeft 番捂, android:drawableTop , android:drawableRight , android:drawableBottom ,的多功能按鈕 如下:
import 'package:flutter/material.dart';
class FunIconButton extends MaterialButton with MaterialButtonWithIconMixin {
FunIconButton({
Key key,
@required VoidCallback onPressed,
ValueChanged<bool> onHighlightChanged,
ButtonTextTheme textTheme,
Color textColor,
Color disabledTextColor,
Color color,
Color disabledColor,
Color focusColor,
Color hoverColor,
Color highlightColor,
Color splashColor,
Brightness colorBrightness,
double elevation,
double highlightElevation,
double disabledElevation,
ShapeBorder shape,
Clip clipBehavior = Clip.none,
FocusNode focusNode,
MaterialTapTargetSize materialTapTargetSize,
Duration animationDuration,
double minWidth,
double height,
Widget leftIcon,
Widget topIcon,
Widget rightIcon,
Widget bottomIcon,
EdgeInsetsGeometry textPadding,
Widget label,
}) : assert(elevation == null || elevation >= 0.0),
assert(highlightElevation == null || highlightElevation >= 0.0),
assert(disabledElevation == null || disabledElevation >= 0.0),
super(
key: key,
onPressed: onPressed,
onHighlightChanged: onHighlightChanged,
textTheme: textTheme,
textColor: textColor,
disabledTextColor: disabledTextColor,
color: color,
disabledColor: disabledColor,
focusColor: focusColor,
hoverColor: hoverColor,
highlightColor: highlightColor,
splashColor: splashColor,
colorBrightness: colorBrightness,
elevation: elevation,
highlightElevation: highlightElevation,
disabledElevation: disabledElevation,
shape: shape,
clipBehavior: clipBehavior,
focusNode: focusNode,
materialTapTargetSize: materialTapTargetSize,
animationDuration: animationDuration,
minWidth: minWidth,
height: height,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Offstage(
offstage: topIcon == null,
child: topIcon,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Offstage(
offstage: leftIcon == null,
child: leftIcon,
),
Padding(
padding: textPadding,
child: label,
),
Offstage(
offstage: rightIcon == null,
child: rightIcon,
),
],
),
Offstage(
offstage: bottomIcon == null,
child: bottomIcon,
),
],
),
);
}
除了支持 Flutter Button中常用的屬性外个唧,我們還添了如下屬性:
屬性名 類型 作用
leftIcon Widget 左邊添加一個圖標(biāo),可以是其他 Widget 組件
topIcon Widget 頂部添加一個圖標(biāo),同理
rightIcon Widget 右邊添加一個圖標(biāo)设预,同理
bottomIcon Widget 底部添加一個圖標(biāo)坑鱼,同理
leftIcon
接收的是一個 Widget 能很好拓展你放其他的組件進去,不一定就是一個圖標(biāo)絮缅,為了更加靈活鲁沥。下面來運用試試。
FunIconButton(
label:Text('多功能按鈕',style: TextStyle(color: Colors.deepPurple)),
color: Colors.blue,
textColor: Colors.white,
onPressed: () {},
minWidth: 240,
leftIcon: Image.asset(
"images/mm.jpg",
width: 24,
height: 24,
),
rightIcon: Icon(Icons.group),
topIcon: Icon(Icons.save),
bottomIcon: Icon(Icons.score),
textPadding: EdgeInsets.only(left: 10, right: 10),
),
效果如下:
二耕魄、FlatButton
FlatButton 沒有 RaisedButton 默認的陰影画恰,因此看起來是扁平化的,沒有凸出感覺吸奴。
FlatButton(
//按鈕文字顏色
textColor: Colors.white,
//按鈕禁用時的背景顏色
disabledColor:Colors.grey,
//按鈕禁用時的文字顏色
disabledTextColor: Colors.grey,
//正常狀態(tài)下的背景顏色
color: Colors.blue,
//按鈕按下時的背景顏色
highlightColor: Colors.blue[700],
//按鈕主題允扇,默認是淺色主題
colorBrightness: Brightness.dark,
//外形
splashColor: Colors.grey,
// button 顯示的文字
child: Text("納尼"),
//圓角邊框
shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
//按鈕點擊回調(diào)
onPressed: () => {},
)
三、OutlineButton 邊框按鈕
OutlineButton 允許我們給 Button 指定 邊框和樣式则奥,開發(fā)中這種 Button 非常常見考润,運用下:
OutlineButton(
child: Text('邊框按鈕'),
onPressed: () {},
),
OutlineButton(
borderSide: BorderSide(color: Colors.pink),
child: Text('邊框按鈕'),
onPressed: () {},
),
效果如下:
四、IconButton 圖標(biāo)按鈕
此 Button 已經(jīng)在案例中使用太多次了读处,常用且簡單糊治。 IconButton 默認實現(xiàn)了高度和寬度的設(shè)置,并且是一個圓形的 Button罚舱,因此在使用 IconButton 的時候我們可以通過 Icon.size 控制圖標(biāo)大小井辜,也能夠控制 padding 屬性绎谦。
//IconButton
IconButton(
splashColor: Colors.pink,
color: Colors.pink,
icon: Icon(Icons.send,size: 50,),
onPressed: () {},
),
IconButton(
splashColor: Colors.pink,
color: Colors.pink,
padding: EdgeInsets.all(0),
icon: Icon(Icons.settings),
onPressed: () {},
)
效果如下:
五、ButtonBar 按鈕組
ButtonBar 可以默認實現(xiàn)一個按鈕組粥脚,通過 children 屬性可以傳入多個 Button窃肠,說白了 ButtonBar 就是一個容器,可以統(tǒng)一管理子元素的位置信息刷允。
構(gòu)造函數(shù):
const ButtonBar({
Key key,
this.alignment = MainAxisAlignment.end,
this.mainAxisSize = MainAxisSize.max,
this.children = const <Widget>[],
}) : super(key: key);
實踐運用:
ButtonBar(
alignment:MainAxisAlignment.center ,
children: <Widget>[
RaisedButton(
color: Colors.pink,
textColor: Colors.white,
child: Text('按鈕組'),
onPressed: () {},
),
FlatButton(
color: Colors.pink,
textColor: Colors.white,
child: Text('按鈕組'),
onPressed: () {},
)
],
)
效果如下:
六冤留、FloatingActionButton 懸浮按鈕
FloatingActionButton 可以實現(xiàn)浮動按鈕,使用場景也是非常多 如:各種購物商場的 返回頂部按鈕树灶。
常用屬性:
屬性名稱 屬性值
child 子視圖纤怒,一般為 Icon
tooltip FAB 被長按時顯示,也是無障礙功能
backgroundColor 背景顏色
foregroundColor 前景色
elevation 未點擊的時候的陰影
hignlightElevation 點擊時陰影值破托,默認 12.0
onPressed 點擊事件回調(diào)
shape 可以定義 FAB 的形狀等
mini 是否是 mini 類型默認 false
heroTag hero效果使用的tag,系統(tǒng)默認會給所有FAB使用同一個tag,方便做動畫效果
isExtended 是否為”extended”類型
簡單運用:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
void handlerDrawerButton() {
}
@override
Widget build(BuildContext context) {
return Scaffold(
//FloatingActionButton
floatingActionButton: FloatingActionButton(
elevation: 0,
backgroundColor: Colors.green,
foregroundColor: Colors.purpleAccent,
child: Icon(
Icons.build,
size: 30,
color: Colors.white,
),
onPressed: () {},
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
backgroundColor: Colors.blue,
body: Container(
child: Center(
child: Text("主頁"),
),
),
);
}
}
效果如下綠色懸浮按鈕:
FloatingActionButton 的不同類型
FAB 分為三種類型:常規(guī), mini, 和 extended肪跋。下面來看這三種有什么區(qū)別:
可以看出 設(shè)置mini
時歧蒋,F(xiàn)AB按鈕變小了土砂。使用FloatingActionButton.extended
構(gòu)造函數(shù)可以實現(xiàn)圖文并茂的懸浮按鈕。
FloatingActionButton 的位置選擇
Scaffold Widget中有一個 floatingActionButtonLocation
屬性 結(jié)合FAB使用谜洽,可以指定懸浮按鈕的擺放位置萝映。
目前提供了 7 種位置可以選擇,在使用時可以分別試試不同的位置效果吧阐虚。
七序臂、模仿閑魚底部導(dǎo)航效果:
為什么要模仿閑魚? 因為他牛逼啊实束,哈哈奥秆。畢竟別人是國內(nèi) Flutter 最大的團隊!O滩印构订!
閑魚的底部菜單按鈕是這樣子的:
結(jié)合上面學(xué)到的按鈕組件 FloatingActionButton 其實我們可以很輕松實現(xiàn)閑魚效果。我們的案例中已經(jīng)有創(chuàng)建好的底部菜單避矢,那就充分利用起來吧悼瘾,進入我們之前寫 Tabs.dart 中,在 Scaffold 配置 floatingActionButton 屬性审胸,之前沒有跟著我寫的同學(xué)亥宿,可以在文末去翻閱源碼。
floatingActionButton:Container(
height: 80,
width: 80,
//實現(xiàn)一個圓形
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
color: Colors.white,
),
//距離上邊 10個單位
margin: EdgeInsets.only(top:10),
// 8個單位的內(nèi)邊距砂沛,讓周邊有浮出感
padding: EdgeInsets.all(8),
child: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: this._currentIndex==1?Colors.red:Colors.deepPurple,
onPressed: (){
setState(() {
this._currentIndex=1;
});
},
),
),
//指定顯示位置
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
最終效果如下:
非常輕松的就實現(xiàn)了烫扼,沒什么難度。O(∩_∩)O哈哈~
下面貼出本章中的全部實例圖碍庵,看圖回憶下本章知識點吧材蛛!
好了本章節(jié)到此結(jié)束圆到,又到了說再見的時候了,如果你喜歡請留下你的小紅星卑吭,你們的支持才是創(chuàng)作的動力芽淡,如有錯誤,請熱心的你留言指正, 謝謝大家觀看豆赏,下章再會 O(∩_∩)O