Widget for Week: Button

Flutter 中 Button 的使用也非常簡單。
Flutter 中的 button 都是 MaterialButton ,這個是基類,所以常見的都是基于他衍生的,官方為我們提供了幾個常用的 button,[FlatButton],[OutlineButton],[RaisedButton],下面就一一介紹,并例舉一些常用的 case 的樣式處理。


image.png

本文基于源碼 1.10.2

  • RaisedButton :凸起的按鈕,其實就是Android中的Material Design風格的Button ,繼承自MaterialButton
  • FlatButton :扁平化的按鈕,繼承自MaterialButton
  • OutlineButton :帶邊框的按鈕,繼承自MaterialButton,其實就是設置了 shape 的 RaisedButton
  • IconButton :圖標按鈕,繼承自StatelessWidget,其實等同于上邊的 Button 設置 child 為 Icon

先來看一下 MaterialButton 的構造函數,屬性是蠻多的。。。從頭說起。

const MaterialButton({
    Key key,
    @required this.onPressed,
    this.onHighlightChanged,
    this.textTheme,
    this.textColor,
    this.disabledTextColor,
    this.color,
    this.disabledColor,
    this.focusColor,
    this.hoverColor,
    this.highlightColor,
    this.splashColor,
    this.colorBrightness,
    this.elevation,
    this.focusElevation,
    this.hoverElevation,
    this.highlightElevation,
    this.disabledElevation,
    this.padding,
    this.shape,
    this.clipBehavior = Clip.none,
    this.focusNode,
    this.autofocus = false,
    this.materialTapTargetSize,
    this.animationDuration,
    this.minWidth,
    this.height,
    this.child,
  })
屬性 值類型 說明
onPressed VoidCallback 必填參數,按下回調,設置為 null 則表示禁用,會啟用禁用的樣式
child Widget Button 上要顯示的組件
textColor Color 組件的顏色,比如child 為 Text 時就是設置了 Text 的字體顏色
color Color button 的顏色
disabledColor Color 按鈕禁用時候的顏色
disabledTextColor Color 按鈕禁用的時候的child 顏色
splashColor Color 水波紋顏色
highlightColor Color 長按時按鈕的顏色
elevation double 陰影的范圍大小,值越大陰影范圍越大
padding EdgeInsetsGeometry 內邊距
shape ShapeBorder 設置形狀
minWidth double 最小寬度
height double 高度

經過上述屬性,基本上就能搭配出來你想要的任何的按鈕樣式了。

RaisedButton 和 FlatButton 都是直接繼承 MaterialButton,所以默認使用的樣式大同小異,唯一區別就是 FlatButton扁平化,沒有凸起的背景色,所以比較適合給 Text 設置點擊事件的。

屬性介紹完畢,相信大家都有個印象,對比自己的 Android 或者 iOS 經驗,也都能腦補出來樣式。。。
下邊就說一下開發中常用的一些樣式。

padding

很多時候,按鈕中間的文字,是需要給一點距離的,文字距離上下左右都有一定邊距,此時就需要用到 padding 屬性,如下代碼就是給 Text 四周設置了 20 的邊距,距離按鈕邊框,當然你也可以用EdgeInsets.only()給具體的某一個(幾個)方向設置邊距,使用EdgeInsets.symmetric()給水平或者垂直方向設置邊距。

 RaisedButton(
              onPressed: () {
                _showSnackBar("RaisedButton 設置內邊距20");
              },
              child: Text("RaisedButton 設置內邊距20"),
              padding: const EdgeInsets.all(20),
            ),

shape

shape 的值是 ShapeBorder ,抽象類,他有幾個常見的實現類

  • BeveledRectangleBorder 帶斜角的長方形邊框
  • CircleBorder 圓形邊框
  • RoundedRectangleBorder 圓角矩形
  • StadiumBorder 兩端是半圓的邊框

對應的都要兩個屬性:slide ,borderRadius

圓角矩形
如下代碼可實現圓角矩形的邊框形狀,當然了如果你要是想實現 iOS 樣式的大圓角的按鈕,只需要把 Radius 的值設置的大一點就行了。

RaisedButton(
              onPressed: () {},
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(10)),
              ),
              child: Text(
                "RaisedButton 圓角背景(小)",
                style: TextStyle(fontSize: 10),
              ),
            ),

iOS 樣式 按鈕
在 IOS 設備上,按鈕都是兩頭半圓樣式的,那么就可以簡單的實現,兩種方案:
1.給RoundedRectangleBorder 的 Radius 設置的超級大
2.直接使用 StadiumBorder()設置為 shape

RaisedButton(
              onPressed: () {},
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(300)),
              ),
              child: Text(
                "RaisedButton 圓角背景(iOS 樣式)",
                style: TextStyle(fontSize: 10),
              ),
            ),
RaisedButton(
              onPressed: () {},
              shape: StadiumBorder(),
              child: Text(
                "StadiumBorder 兩頭半圓",
                style: TextStyle(fontSize: 10),
              ),
            ),

圓形按鈕
使用 CircleBorder 可以實現圓形的按鈕樣式

RaisedButton(
              onPressed: () {},
              padding: const EdgeInsets.all(20),
              shape: CircleBorder(),
              child: Text(
                "圓形樣式",
                style: TextStyle(fontSize: 10),
              ),
            ),

斜角的矩形
實現帶斜角的矩形,也很簡單,直接使用BeveledRectangleBorder就行了,BorderRadius 的值的大小,可以幫助你實現各式各樣的斜角。。。
值越大,斜的越厲害,如果設置為 0,就是標準的矩形。

RaisedButton(
              color: Colors.red,
              onPressed: () {},
              shape: BeveledRectangleBorder(
                  borderRadius: BorderRadius.circular(10)),
              child: Text(
                "StadiumBorder 兩頭半圓",
                style: TextStyle(fontSize: 10),
              ),
            ),

以上實現的一些樣式,都是純色的,單純的背景色,下邊再來實現一些帶邊框的樣式,
BorderShape 的幾個實現類里邊,都有兩個屬性:slide 和 borderRadius.
slide 屬性可以設置背景色,邊框顏色,邊框的背景等
borderRadius 就是設置弧形程度。

實現一個紅色邊框,寬度為 1,白色背景的邊框
紅色邊框用 side 里邊的 color 來設置,寬度用 width 設置

 RaisedButton(
              onPressed: () {},
              color: Colors.white,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10),
                  side: BorderSide(color: Colors.red)),
              child: Text("RaisedButton"),
            ),

漸變色按鈕
Flutter 中的按鈕不支持實現漸變色,所以需要依靠 Container 來幫忙,只需要給按鈕的 child套一個 Container,給 Container 設置漸變色就行了。但是需要考慮到處理 button 自帶的默認的內邊距,一定要記得去掉,不然會很難看。。。

Theme(
              child: RaisedButton(
                onPressed: () {},
                elevation: 0.0,
                color: Colors.white,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10),
                ),
                child: Container(
                  child: Text("RaisedButton"),
                  padding: EdgeInsets.fromLTRB(16, 8, 16, 8),
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10),
                      gradient:
                          LinearGradient(colors: [Colors.green, Colors.red])),
                ),
              ),
              data: ThemeData().copyWith(
                  buttonTheme:
                      ButtonThemeData(padding: const EdgeInsets.all(0))),
            ),

不知道大家有沒有發現,按鈕在使用過程中,有一個自己的默認的寬高,仔細看看源碼,發現是在按鈕的主題里邊設置了,如下代碼,
所以如果你想去掉這個默認值,可以在 Theme 里邊進行設置,可以直接在最外層的 MaterialApp 中設置,也可以給按鈕嵌套一個 Theme()進行處理。如下代碼采用了第二個方案。

ButtonThemeData({
    this.textTheme = ButtonTextTheme.normal,
    this.minWidth = 88.0,
    this.height = 36.0,
    EdgeInsetsGeometry padding,
    ShapeBorder shape,
    this.layoutBehavior = ButtonBarLayoutBehavior.padded,
    this.alignedDropdown = false,
    Color buttonColor,
    Color disabledColor,
    Color focusColor,
    Color hoverColor,
    Color highlightColor,
    Color splashColor,
    this.colorScheme,
    MaterialTapTargetSize materialTapTargetSize,
  })
 Theme(
              child: RaisedButton(
                onPressed: () {},
                color: Colors.white,
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10),
                    side: BorderSide(color: Colors.red, width: 4)),
                child: Text("去掉默認寬高"),
              ),
              data: ThemeData().copyWith(
                  buttonTheme: ButtonThemeData(minWidth: 10, height: 20)),
            ),

帶圖片/圖標的按鈕
有時候需要實現一些帶有圖標的按鈕,那么可以用 RaisedButton ,通過 child 嵌套實現,也可以直接使用 IconButton

 RaisedButton(
              onPressed: () {},
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[Icon(Icons.add), Text("帶圖標")],
              ),
            ),
            SizedBox(width: 10),
            FlatButton(
              onPressed: () {},
              child: Icon(
                Icons.add,
                color: Colors.red,
              ),
            ),
            SizedBox(width: 10),
            IconButton(
              onPressed: () {},
              icon: Icon(
                Icons.add,
                color: Colors.red,
              ),
            ),

OK,今日份 按鈕相關內容搞定,后續有遇到其他的樣式,再更新進來。。。

源碼鏈接:https://github.com/yanftch/book/blob/master/lib/demo/widgets/w_button.dart

收拾收拾,放假啦~~
預祝小伙伴們假期愉快??????

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。