是一个便利的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, ), )