Flutter布局---Container

簡介

A convenience widget that combines common painting, positioning, and sizing widgets.

Container 在Flutter中非常常見, 是一個結(jié)合繪制(painting), 定位(position)以及尺寸(sizing)的widget.

組成

Container的組成如下:

  • 最里層的是child元素;
  • child元素首先會被padding包著;
  • 然后添加額外的constraints限制;
  • 最后添加margin.

Container的繪制的過程如下:

  • 首先會繪制transform效果;
  • 接著繪制decoration;
  • 后繪制child;
  • 最后繪制foregroundDecoration.

Container自身尺寸的調(diào)節(jié)分兩種情況:

  • Container在沒有子節(jié)點(children)的時候,會試圖去變得足夠大。除非constraints是unbounded限制走诞,在這種情況下会油,Container會試圖去變得足夠小。
  • 帶子節(jié)點的Container贾费,會根據(jù)子節(jié)點尺寸調(diào)節(jié)自身尺寸钦购,但是Container構(gòu)造器中如果包含了width、height以及constraints褂萧,則會按照構(gòu)造器中的參數(shù)來進行尺寸的調(diào)節(jié)押桃。
源碼解析

構(gòu)造函數(shù)如下:

Container({
    Key key,
    this.alignment,
    this.padding,
    Color color,
    Decoration decoration,
    this.foregroundDecoration,
    double width,
    double height,
    BoxConstraints constraints,
    this.margin,
    this.transform,
    this.child,
  })

屬性解析

key:Container唯一標識符,用于查找更新导犹。

alignment:控制child的對齊方式虎眨,如果container或者container父節(jié)點尺寸大于child的尺寸弯淘,這個屬性設(shè)置會起作用,有很多種對齊方式。

padding:decoration內(nèi)部的空白區(qū)域譬重,如果有child的話,child位于padding內(nèi)部尝抖。padding與margin的不同之處在于伴嗡,padding是包含在content內(nèi),而margin則是外部邊界,設(shè)置點擊事件的話纫骑,padding區(qū)域會響應(yīng)蝎亚,而margin區(qū)域不會響應(yīng)。

color:用來設(shè)置container背景色先馆,如果foregroundDecoration設(shè)置的話发框,可能會遮蓋color效果。

decoration:繪制在child后面的裝飾煤墙,設(shè)置了decoration的話梅惯,就不能設(shè)置color屬性,否則會報錯仿野,此時應(yīng)該在decoration中進行顏色的設(shè)置铣减。

foregroundDecoration:繪制在child前面的裝飾。

width:container的寬度脚作,設(shè)置為double.infinity可以強制在寬度上撐滿葫哗,不設(shè)置,則根據(jù)child和父節(jié)點兩者一起布局球涛。

height:container的高度劣针,設(shè)置為double.infinity可以強制在高度上撐滿。

constraints:添加到child上額外的約束條件亿扁。

margin:圍繞在decoration和child之外的空白區(qū)域捺典,不屬于內(nèi)容區(qū)域。

transform:設(shè)置container的變換矩陣从祝,類型為Matrix4襟己。

child:container中的內(nèi)容widget。

源碼
decoration = decoration ?? (color != null ? new BoxDecoration(color: color) : null),

可以看出, 對于顏色的設(shè)置哄褒,最后都是轉(zhuǎn)換為decoration來進行繪制的稀蟋。如果同時包含decoration和color兩種屬性,則會報錯呐赡。

@override
  Widget build(BuildContext context) {
    Widget current = child;

    if (child == null && (constraints == null || !constraints.isTight)) {
      current = new LimitedBox(
        maxWidth: 0.0,
        maxHeight: 0.0,
        child: new ConstrainedBox(constraints: const BoxConstraints.expand())
      );
    }

    if (alignment != null)
      current = new Align(alignment: alignment, child: current);

    final EdgeInsetsGeometry effectivePadding = _paddingIncludingDecoration;
    if (effectivePadding != null)
      current = new Padding(padding: effectivePadding, child: current);

    if (decoration != null)
      current = new DecoratedBox(decoration: decoration, child: current);

    if (foregroundDecoration != null) {
      current = new DecoratedBox(
        decoration: foregroundDecoration,
        position: DecorationPosition.foreground,
        child: current
      );
    }

    if (constraints != null)
      current = new ConstrainedBox(constraints: constraints, child: current);

    if (margin != null)
      current = new Padding(padding: margin, child: current);

    if (transform != null)
      current = new Transform(transform: transform, child: current);

    return current;
  }

Container 的 build 函數(shù)的繪制過程是一個線形的判斷過程, 一層層的包裹著Widget, 去實現(xiàn)不同的樣式.

示例
void main() => runApp(MyApp());


class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePage createState() => _MyHomePage();
}

class _MyHomePage extends State<MyHomePage> {

  String textToShow = "I like Flutter";

  void _updateText(){
    print('點擊');
    setState(() {
      textToShow = "Flutter is Awesome";
    });
    Navigator.push(
      context,
      new MaterialPageRoute(builder: (context) => new SamplePage())
    );
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
          title: Text("Sample App")
      ),
      body: new Container(
        constraints: new BoxConstraints.expand(
          height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 200
        ),
        decoration: new BoxDecoration(
          border: new Border.all(width: 2.0, color: Colors.red),
          color: Colors.grey,
          borderRadius: new BorderRadius.all(new Radius.circular(20)),
          image: new DecorationImage(
              image: new NetworkImage('http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
              centerSlice: new Rect.fromLTRB(270, 180, 1360, 730)
          ),
        ),
        padding: const EdgeInsets.all(8.0),
        alignment: Alignment.center,
        child: new Text(textToShow,
          style: Theme.of(context).textTheme.display1.copyWith(color: Colors.black),
        ),
        transform: new Matrix4.rotationZ(0.3),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: _updateText,
          tooltip: 'Update Text',
          child: Icon(Icons.update),
      ),
    );
  }
}
屏幕快照 2019-07-29 下午2.57.48.png
使用場景
  • 需要設(shè)置間隔
  • 需要設(shè)置背景
  • 需要設(shè)置圓角或者邊框
  • 需要對齊
  • 需要設(shè)置背景圖片
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末退客,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子链嘀,更是在濱河造成了極大的恐慌萌狂,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怀泊,死亡現(xiàn)場離奇詭異茫藏,居然都是意外死亡,警方通過查閱死者的電腦和手機霹琼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門务傲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凉当,“玉大人,你說我怎么就攤上這事售葡】春迹” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵挟伙,是天一觀的道長楼雹。 經(jīng)常有香客問我,道長尖阔,這世上最難降的妖魔是什么贮缅? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮介却,結(jié)果婚禮上谴供,老公的妹妹穿的比我還像新娘。我一直安慰自己筷笨,他們只是感情好憔鬼,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布龟劲。 她就那樣靜靜地躺著胃夏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昌跌。 梳的紋絲不亂的頭發(fā)上仰禀,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音蚕愤,去河邊找鬼答恶。 笑死,一個胖子當著我的面吹牛萍诱,可吹牛的內(nèi)容都是我干的悬嗓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼裕坊,長吁一口氣:“原來是場噩夢啊……” “哼包竹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起籍凝,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤周瞎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后饵蒂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體声诸,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年退盯,在試婚紗的時候發(fā)現(xiàn)自己被綠了彼乌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泻肯。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖慰照,靈堂內(nèi)的尸體忽然破棺而出软免,到底是詐尸還是另有隱情,我是刑警寧澤焚挠,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布膏萧,位于F島的核電站,受9級特大地震影響蝌衔,放射性物質(zhì)發(fā)生泄漏榛泛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一噩斟、第九天 我趴在偏房一處隱蔽的房頂上張望曹锨。 院中可真熱鬧,春花似錦剃允、人聲如沸沛简。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椒楣。三九已至,卻和暖如春牡肉,著一層夾襖步出監(jiān)牢的瞬間捧灰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工统锤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毛俏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓饲窿,卻偏偏與公主長得像煌寇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逾雄,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容