是一個便利的Widget,它把通用的繪製、定位和Widget的大小結合了起來。
Container會先用padding填充子Widget和border之間的空白,而後添加其餘的額外的約束constraints,最後會把剩餘的都用margin來填充。
在繪製的過程當中,會優先繪製transform,而後是decoration,最後是foregroundDecoration。
對於一個沒有子Widget的Container,在沒有一些約束的條件時,它會盡量的大;而一旦有了約束或者子Widget,它就會變得儘量小。
下面是代碼演示時間:
css
static _baseContainer() { return new Container( color: Colors.red, ); }
此時的截圖以下:
發現它儘量的佔了所有。
此時,設置padding是不起做用的。java
static _addWidgetToContainer() { return new Container( color: Colors.red, child: new Text("Container"), ); }
此時變成了下面的樣子:
它幾乎和子Widget貼合到了一塊兒了。app
static _limitWidth() { return new Container( color: Colors.red, child: new Text("Container"), width: 20.0, // width: 200.0, // height: 10.0, ); }
能夠確定,文字的寬度要比20大,由於此時沒有限制高度,因此會展現成下面的樣子:
能夠發現它的高度自動變大了,直到能把全部的內容容納下來。ide
當限制了高度的時候
函數
當限制了寬和高的時候
字體
static _limitWidthWithPadding() { return new Container( color: Colors.red, padding: const EdgeInsets.all(20.0), height: 20.0, width: 20.0, child: new Text("Container"), ); }
static _boxContraints() { return new Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Container( // 至關於直接制定了該Container的寬和高,且它的優先級要高於width和height constraints: new BoxConstraints.expand(width: 250.0, height: 150.0), color: Colors.red, width: 100.0, height: 100.0, // 設置Container的最大和最小寬度和高度 // constraints: new BoxConstraints( // maxWidth: 50.0, // ), ), new Container( color: Colors.green, width: 100.0, height: 100.0, ) ], ); }
這裏主要展現了它的默認初始化和指定初始化方法的Expand,其中後者就至關於直接制定了該Container的寬和高。flex
foregroundDecoration
動畫
static _foregroundDecoration() { return new Center( child: new Container( color: Colors.red, constraints: new BoxConstraints.expand(width: 300.0, height: 300.0,), foregroundDecoration: new BoxDecoration( color: Colors.blue, border: new Border.all(color: Colors.yellow, width: 5.0,), borderRadius: new BorderRadius.all(new Radius.circular(50.0)), gradient: new LinearGradient(colors: [Colors.blue, Colors.green]), ), alignment: Alignment.center, child: new Text("Container"), ), ); }
能夠發現,對於有背景圖的Container,只是簡單的切圓角是有問題的;並且它還會堵住子Widget。ui
decoration
this
static _decoration() { return new Center( child: new Container( // color: Colors.red, // 不能和decoration共存 constraints: new BoxConstraints.expand(width: 300.0, height: 300.0,), alignment: Alignment.center, child: new Text("Container"), decoration: new BoxDecoration( color: Colors.blue, border: new Border.all(color: Colors.yellow, width: 5.0,), borderRadius: new BorderRadius.all(new Radius.circular(50.0)), gradient: new LinearGradient(colors: [Colors.blue, Colors.green]), ), ), ); }
Row在前面聊過,最主要注意的一點就是內容不能超過邊界,不然會出錯誤。
這裏補充的是若是使用了Expanded,那麼其中的Widget的尺寸就再也不起做用。以下:
static _baseRow() { return new Container( color: Colors.red, height: 300.0, child: new Row( // 會超出去,展現錯誤 // children: <Widget>[ // new Container(width: 200.0, color: Colors.green,), // new Container(width: 200.0, color: Colors.blue,), // new Container(width: 200.0, color: Colors.cyan,), // ], children: <Widget>[ // 使用了Expanded後,尺寸再也不起做用 new Expanded(child: new Container(width: 50.0, color: Colors.green,)), new Expanded(child: new Container(width: 100.0, color: Colors.blue,)), new Expanded(child: new Container(width: 100.0, color: Colors.cyan,)), ], ), ); }
這裏的使用了Expanded的Container就不會再起做用
有兩種初始化方法,Text和Text.rich。
Icon是不響應事件的,IconButton能夠。
默認狀況下,能夠看到被點擊中的按鈕浮起來了。
具體的詳細說明以下:
raisedButtonWithChild() {
return new Center( child: new RaisedButton( onPressed: this.clickedRaisedButton, color: Colors.green, // child: new Text('Raised Button', style: new TextStyle(color: Colors.black),), child: new Text( 'Raised Button', ), textColor: Colors.white, // 該按鈕上的文字顏色,可是前提是不設置字體自身的顏色時纔會起做用 // highlightColor: Colors.yellow, // 高亮時的背景色 disabledColor: Colors.deepOrange, // 失效時的背景色 disabledTextColor: Colors.grey, // 按鈕失效時的文字顏色,一樣的不能使用文本本身的樣式或者顏色時纔會 起做用 splashColor: Colors.purple, // 點擊按鈕時的漸變背景色,當你不設置高亮背景時纔會看的更清楚 colorBrightness: Brightness.dark, // 這個我也不知道 elevation: 15.0, // 正常狀況下浮動的距離 highlightElevation: 5.0, // 高亮時的浮動距離(能夠嘗試將該值設置的比elevation小,看看體驗) disabledElevation: 50.0, padding: const EdgeInsets.all(20.0), shape: new Border.all( // 設置邊框樣式 color: Colors.blue, width: 4.0, style: BorderStyle.solid, ), animationDuration: new Duration( // 過程時間,最容易觀察的是從elevation到highlightElevation,或者相反過程,可是前提是要完全的按下去,注意其影子的變化 seconds: 5, ), onHighlightChanged: this.hightLightChanged, // 能夠用來監聽按鈕的按下和放開過程 textTheme: ButtonTextTheme.accent, // 搞不懂這個 ), ); }
該方法獲得的RaisedButton默認有兩個Widget,並且是必傳的;其餘參數都和直接初始化沒什麼區別。具體的代碼以下:
raisedButtonWithIcon() {
return new Center( child: new RaisedButton.icon( onPressed: this.clickedRaisedButton, icon: new Icon(Icons.star), label: new Text('RaisedButton'), ), ); }
效果圖以下:
class AppBarWidget extends StatefulWidget { @override State<StatefulWidget> createState() => new AppBarState(); } class AppBarState extends State<AppBarWidget> { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp( debugShowCheckedModeBanner: false, // 在調試期間,右上角的DEBUG字樣 home: new Scaffold( appBar: new AppBar( title: new Text( 'AppBar', style: new TextStyle( // 設置字體樣式 color: Colors.white, fontWeight: FontWeight.bold, ), ), // title // centerTitle: true, // 當設置了actions以後,title的位置會發生變化,使用該屬性,可讓標題忽略actions佔去的空間居中 // titleSpacing: 0.0, elevation: 0.0, // 下部的影子,該值越大,影子越清楚,爲0時,不會有影子,和RaisedButton是同樣的 backgroundColor: Colors.cyan, // 背景色 leading: this.appBarLeading(), actions: this.appBarActions(), bottom: null, // 這個先放一放 // flexibleSpace: new FlexibleSpaceBar( // 這個有什麼用呢????貌似是說只有在appbar的size改變的時候纔會起做用 // title: new Text('Flexible'), // // centerTitle: false, // ), ), ), ); } appBarActions() { return <Widget>[ new Container( width: 50.0, child: new Icon( Icons.star_border, color: Colors.red, ), ), new Container( width: 50.0, child: new Icon(Icons.share), ), new Container( color: Colors.orange, width: 50.0, margin: const EdgeInsets.only( left: 5.0, right: 5.0, ), alignment: Alignment.center, child: new Text('actions'), ), ]; } // 通過實驗發現,leading是限制了大小的 appBarLeading() { return new RaisedButton( onPressed: this.clickedLeadingBtn, child: new Text( 'Leading', ), textColor: Colors.white, color: Colors.red, elevation: 0.0, disabledElevation: 0.0, highlightElevation: 0.0, // highlightColor: Colors.cyan, colorBrightness: Brightness.light, splashColor: Colors.red, padding: const EdgeInsets.all(5.0), ); } clickedLeadingBtn() { print('Clicked Leading'); } }
用來展現Flutter的logo的,真是任性啊,爲了一個Logo,專門寫了一個Widget。
class _FlutterLogoState extends State<_FlutterLogoWidget> { var _status = 0; clickedToChangeStatus() { setState(() { _status = (_status + 1) % 3; }); } @override Widget build(BuildContext context) { // TODO: implement build FlutterLogoStyle style = FlutterLogoStyle.markOnly; if (_status == 1) { style = FlutterLogoStyle.horizontal; } else if (_status == 2) { style = FlutterLogoStyle.stacked; } return new Center( child: new Column( children: <Widget>[ new Container( margin: const EdgeInsets.only( top: 30.0, bottom: 30.0, ), child: new RaisedButton( onPressed: this.clickedToChangeStatus, color: Colors.green, child: new Text('Change Status'), ), ), new FlutterLogo( size: 50.0, colors: Colors.red, // 圖的顏色 textColor: Colors.orange, // 只對帶文字的style起做用 // style: FlutterLogoStyle.markOnly, // 只有圖 style: style, // 左圖右文 // style: FlutterLogoStyle.stacked, // 上圖下文 duration: new Duration( // 當colors、textColor或者style變化的時候起做用 seconds: 3, ), curve: Curves.elasticOut, // 動畫方式 ) ], ), ); } }
代碼也很簡單,甚至不用多寫任何東西,只要初始化了就好了。
new Container( width: 100.0, margin: const EdgeInsets.only(top: 30.0), child: new Placeholder( fallbackWidth: 100.0, fallbackHeight: 100.0, color: Colors.orange, ), )