flutter Container設(shè)置固定的寬和高后為什么不生效?

1. 為什么Container設(shè)置width和height不生效?

下面這段代碼瞄崇,Container設(shè)置了(width: 100, height: 100),但渲染出來是填充滿屏幕的婿屹,這是為什么?

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(width: 100, height: 100, color: Colors.red);
  }
}

可以從Container的初始化和build方法看下具體原因:

Container({
  double? width,
  double? height,
  ...
}) : 
     constraints =
      (width != null || height != null)
        ? constraints?.tighten(width: width, height: height)
          ?? BoxConstraints.tightFor(width: width, height: height)
        : constraints,
     super(key: key);
     
@override
Widget build(BuildContext context) {
  Widget? current = child;

  if (color != null)
    current = ColoredBox(color: color!, child: current);

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

  return current!;
}

從Container初始化可以看出constraints是一個(gè)緊約束,寬高是100。


image.png

通過build方法生成ColoredBox和ConstrainedBox,其對(duì)應(yīng)的渲染類為_RenderColoredBox和RenderConstrainedBox溢十。其對(duì)應(yīng)關(guān)系如下:

image.png

flutter約束有下面特點(diǎn):


image.png

可以理解RenderConstrainedBox的約束是從父節(jié)點(diǎn)向下傳遞截粗,而大小是從_RenderColoredBox向上傳遞信姓。

constraints是怎么來的鸵隧?

constraints是通過RenderView.performLayout傳遞逐級(jí)傳遞下來的,此時(shí)的constraints是一個(gè)緊約束,寬高就是屏幕的高度。


image.png

_additionalConstraints是RenderConstrainedBox初始化傳遞進(jìn)來的約束意推,也就是開始設(shè)置的(100,100)

_additionalConstraints.enforce(constraints)是決定了當(dāng)前size的大小:

//BoxConstraints
BoxConstraints enforce(BoxConstraints constraints) {
  return BoxConstraints(
    minWidth: minWidth.clamp(constraints.minWidth, constraints.maxWidth),
    maxWidth: maxWidth.clamp(constraints.minWidth, constraints.maxWidth),
    minHeight: minHeight.clamp(constraints.minHeight, constraints.maxHeight),
    maxHeight: maxHeight.clamp(constraints.minHeight, constraints.maxHeight),
  );
}

_additionalConstraints是Container的約束(100,100),constraints是屏幕傳遞下來的寬度和高度(414,896)豆瘫。_additionalConstraints.enforce(constraints)最后產(chǎn)生的結(jié)果就是屏幕的高度和寬度。而這個(gè)約束繼續(xù)傳遞給_RenderColoredBox進(jìn)行繪制顏色,這也解釋了為什么Container設(shè)置了寬高不生效的原因菊值。

2. 修改上面代碼,再想想結(jié)果是什么外驱?

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(width: 100, height: 100, color: Colors.red),
    );
  }
}

直接看下Center繼承自Align,其對(duì)應(yīng)的RenderObject是RenderPositionedBox,而performLayout方法做了什么?

@override
void performLayout() {
  ...
  if (child != null) {
    child!.layout(constraints.loosen(), parentUsesSize: true);
    ...
  } else {
    ...
  }

child.layout傳遞的是constraints.loosen(),

BoxConstraints(
  minWidth: 0.0,
  maxWidth: maxWidth,
  minHeight: 0.0,
  maxHeight: maxHeight,
)

maxWidth和maxHeight是double.infinity,也就是(100,100).enforce(constraints)返回是(100,100)腻窒。這就很好的解釋了為什么Center包裹之后child就生效了昵宇。

如果了解約束的原理,下面的兩個(gè)題應(yīng)該很容易得出結(jié)果:

ConstrainedBox(
  constraints: const BoxConstraints(
    minWidth: 70,
    minHeight: 70,
    maxWidth: 150,
    maxHeight: 150,
  ),
  child: Container(color: Colors.red, width: 10, height: 10),
)

Center(
  child: ConstrainedBox(
    constraints: const BoxConstraints(
      minWidth: 70,
      minHeight: 70,
      maxWidth: 150,
      maxHeight: 150,
    ),
    child: Container(color: red, width: 1000, height: 1000),
  ),
)

總結(jié):
約束是從父類向下傳遞的,在計(jì)算自身layout時(shí)會(huì)用自身的約束與父類約束做一個(gè)收縮儿子,只有當(dāng)子約束的最大最小高度和寬度都是在父控件的范圍內(nèi)才生效瓦哎。否則以父約束的臨界點(diǎn)生效。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末典徊,一起剝皮案震驚了整個(gè)濱河市杭煎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卒落,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜂桶,死亡現(xiàn)場(chǎng)離奇詭異儡毕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扑媚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門腰湾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疆股,你說我怎么就攤上這事费坊。” “怎么了旬痹?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵附井,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我两残,道長(zhǎng)永毅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任人弓,我火速辦了婚禮沼死,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘崔赌。我一直安慰自己意蛀,他們只是感情好耸别,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著县钥,像睡著了一般太雨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上魁蒜,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天囊扳,我揣著相機(jī)與錄音,去河邊找鬼兜看。 笑死锥咸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的细移。 我是一名探鬼主播搏予,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼弧轧!你這毒婦竟也來了雪侥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤精绎,失蹤者是張志新(化名)和其女友劉穎速缨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體代乃,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旬牲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搁吓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片原茅。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖堕仔,靈堂內(nèi)的尸體忽然破棺而出擂橘,到底是詐尸還是另有隱情,我是刑警寧澤摩骨,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布通贞,位于F島的核電站,受9級(jí)特大地震影響仿吞,放射性物質(zhì)發(fā)生泄漏滑频。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一唤冈、第九天 我趴在偏房一處隱蔽的房頂上張望峡迷。 院中可真熱鬧,春花似錦、人聲如沸绘搞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夯辖。三九已至琉预,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蒿褂,已是汗流浹背圆米。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留啄栓,地道東北人娄帖。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像昙楚,于是被迫代替她去往敵國(guó)和親近速。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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