免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Flutter 布局(三)- FittedBox、AspectRatio、ConstrainedBox詳解

本文主要介紹Flutter布局中的FittedBox、AspectRatio、ConstrainedBox,詳細(xì)介紹了其布局行為以及使用場(chǎng)景,并對(duì)源碼進(jìn)行了分析。

1. FittedBox

Scales and positions its child within itself according to fit.

1.1 簡(jiǎn)介

按照其官方的介紹,它主要做了兩件事情,縮放(Scale)以及位置調(diào)整(Position)。

FittedBox會(huì)在自己的尺寸范圍內(nèi)縮放并且調(diào)整child位置,使得child適合其尺寸。做過(guò)移動(dòng)端的,可能會(huì)聯(lián)想到ImageView控件,它是將圖片在其范圍內(nèi),按照規(guī)則,進(jìn)行縮放位置調(diào)整。FittedBox跟ImageView是有些類(lèi)似的,可以猜測(cè)出,它肯定有一個(gè)類(lèi)似于ScaleType的屬性。

1.2 布局行為

FittedBox的布局行為還算簡(jiǎn)單,官方?jīng)]有給出說(shuō)明,我在這里簡(jiǎn)單說(shuō)一下。由于FittedBox是一個(gè)容器,需要讓其child在其范圍內(nèi)縮放,因此其布局行為分兩種情況:

  • 如果外部有約束的話,按照外部約束調(diào)整自身尺寸,然后縮放調(diào)整child,按照指定的條件進(jìn)行布局;
  • 如果沒(méi)有外部約束條件,則跟child尺寸一致,指定的縮放以及位置屬性將不起作用。

1.3 繼承關(guān)系

Object > Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > SingleChildRenderObjectWidget > FittedBox

從繼承關(guān)系可以看出,F(xiàn)ittedBox控件是一個(gè)基礎(chǔ)控件。

1.4 示例代碼

new Container(  color: Colors.amberAccent,  width: 300.0,  height: 300.0,  child: new FittedBox(    fit: BoxFit.contain,    alignment: Alignment.topLeft,    child: new Container(      color: Colors.red,      child: new Text("FittedBox"),    ),  ),)

寫(xiě)了一個(gè)很簡(jiǎn)單的例子,加入Container是為了加顏色顯示兩個(gè)區(qū)域,讀者可以試著修改fit以及alignment查看其不同的效果。

1.5 源碼解析

const FittedBox({Key key,this.fit: BoxFit.contain,this.alignment: Alignment.center,Widget child,})

1.5.1 屬性解析

fit:縮放的方式,默認(rèn)的屬性是BoxFit.contain,child在FittedBox范圍內(nèi),盡可能的大,但是不超出其尺寸。這里注意一點(diǎn),contain是保持著child寬高比的大前提下,盡可能的填滿(mǎn),一般情況下,寬度或者高度達(dá)到最大值時(shí),就會(huì)停止縮放。

alignment:對(duì)齊方式,默認(rèn)的屬性是Alignment.center,居中顯示child。

1.5.2 源碼

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

@overrideRenderFittedBox createRenderObject(BuildContext context) {return new RenderFittedBox(  fit: fit,  alignment: alignment,  textDirection: Directionality.of(context),);}

FittedBox具體實(shí)現(xiàn)是由RenderFittedBox進(jìn)行的。不知道讀者有沒(méi)有發(fā)現(xiàn),目前的一些基礎(chǔ)控件,繼承自RenderObjectWidget的,widget本身都只是存儲(chǔ)了一些配置信息,真正的繪制渲染,則是由內(nèi)部的createRenderObject所調(diào)用的RenderObject去實(shí)現(xiàn)的。

RenderFittedBox具體的布局代碼如下:

if (child != null) {  child.layout(const BoxConstraints(), parentUsesSize: true);  // 如果child不為null,則按照child的尺寸比率縮放child的尺寸  size = constraints.constrainSizeAndAttemptToPreserveAspectRatio(child.size);  _clearPaintData();} else {  // 如果child為null,則按照最小尺寸進(jìn)行布局  size = constraints.smallest;}

1.6 使用場(chǎng)景

FittedBox在目前的項(xiàng)目中還未用到過(guò)。對(duì)于需要縮放調(diào)整位置處理的,一般都是圖片。筆者一般都是使用Container中的decoration屬性去實(shí)現(xiàn)相應(yīng)的效果。對(duì)于其他控件需要縮放以及調(diào)整位置的,目前還沒(méi)有遇到使用場(chǎng)景,大家只需要知道有這么一個(gè)控件,可以實(shí)現(xiàn)這個(gè)功能即可。

2. AspectRatio

A widget that attempts to size the child to a specific aspect ratio.

2.1 簡(jiǎn)介

AspectRatio的作用是調(diào)整child到設(shè)置的寬高比,這種控件在其他移動(dòng)端平臺(tái)上一般都不會(huì)提供,F(xiàn)lutter之所以提供,我想最大的原因,可能就是自定義起來(lái)特別麻煩吧。

2.2 布局行為

AspectRatio的布局行為分為兩種情況:

  • AspectRatio首先會(huì)在布局限制條件允許的范圍內(nèi)盡可能的擴(kuò)展,widget的高度是由寬度和比率決定的,類(lèi)似于BoxFit中的contain,按照固定比率去盡量占滿(mǎn)區(qū)域。
  • 如果在滿(mǎn)足所有限制條件過(guò)后無(wú)法找到一個(gè)可行的尺寸,AspectRatio最終將會(huì)去優(yōu)先適應(yīng)布局限制條件,而忽略所設(shè)置的比率。

2.3 繼承關(guān)系

Object > Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > SingleChildRenderObjectWidget > AspectRatio

從繼承關(guān)系看,AspectRatio是基礎(chǔ)的布局控件。

2.4 示例代碼

new Container(  height: 200.0,  child: new AspectRatio(    aspectRatio: 1.5,    child: new Container(      color: Colors.red,    ),  ),);

示例代碼是定義了一個(gè)高度為200的區(qū)域,內(nèi)部AspectRatio比率設(shè)置為1.5,最終AspectRatio的是寬300高200的一個(gè)區(qū)域。

2.5 源碼解析

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

const AspectRatio({Key key,@required this.aspectRatio,Widget child}) 

構(gòu)造函數(shù)只包含了一個(gè)aspectRatio屬性,其中aspectRatio不能為null。

2.5.1 屬性解析

aspectRatio:aspectRatio是寬高比,最終可能不會(huì)根據(jù)這個(gè)值去布局,具體則要看綜合因素,外層是否允許按照這種比率進(jìn)行布局,只是一個(gè)參考值。

2.5.2 源碼

@override  RenderAspectRatio createRenderObject(BuildContext context) => new RenderAspectRatio(aspectRatio: aspectRatio);

經(jīng)過(guò)前面一些控件的解析,我想大家對(duì)這種構(gòu)造應(yīng)該不會(huì)再陌生了,繪制都是交由RenderObject去完成的,這里則是由RenderAspectRatio去完成具體的繪制工作。

RenderAspectRatio的構(gòu)造函數(shù)中會(huì)對(duì)aspectRatio做一些檢測(cè)(assert)

  • aspectRatio不能為null;
  • aspectRatio必須大于0;
  • aspectRatio必須是有限的。

接下來(lái)我們來(lái)看一下RenderAspectRatio的具體尺寸計(jì)算函數(shù):

  • 如果限制條件為isTight,則返回最小的尺寸(constraints.smallest);
if (constraints.isTight)  return constraints.smallest;
  • 如果寬度為有限的值,則將高度設(shè)置為width / _aspectRatio。 如果寬度為無(wú)限,則將高度設(shè)為最大高度,寬度設(shè)為height * _aspectRatio;
if (width.isFinite) {  height = width / _aspectRatio;} else {  height = constraints.maxHeight;  width = height * _aspectRatio;}
  • 接下來(lái)則是在限制范圍內(nèi)調(diào)整寬高,總體思想則是寬度優(yōu)先,大于最大值則設(shè)為最大值,小于最小值,則設(shè)為最小值。

如果寬度大于最大寬度,則將其設(shè)為最大寬度,高度設(shè)為width / _aspectRatio;

if (width > constraints.maxWidth) {  width = constraints.maxWidth;  height = width / _aspectRatio;}

如果高度大于最大高度,則將其設(shè)為最大高度,寬度設(shè)為height * _aspectRatio;

if (height > constraints.maxHeight) {  height = constraints.maxHeight;  width = height * _aspectRatio;}

如果寬度小于最小寬度,則將其設(shè)為最小寬度,高度設(shè)為width / _aspectRatio;

if (width < constraints.minWidth) {  width = constraints.minWidth;  height = width / _aspectRatio;}

如果高度小于最小高度,則將其設(shè)為最小高度,寬度設(shè)為height * _aspectRatio。

if (height < constraints.minHeight) {  height = constraints.minHeight;  width = height * _aspectRatio;}

2.6 使用場(chǎng)景

AspectRatio適用于需要固定寬高比的情景下。筆者最近使用這個(gè)控件的場(chǎng)景是相機(jī),相機(jī)的預(yù)覽尺寸都是固定的幾個(gè)值,因此不能隨意去設(shè)置相機(jī)的顯示區(qū)域,必須按照比率進(jìn)行顯示,否則會(huì)出現(xiàn)拉伸的情況。除此之外,倒是用的不多。

3. ConstrainedBox

A widget that imposes additional constraints on its child.

3.1 簡(jiǎn)介

這個(gè)控件的作用是添加額外的限制條件(constraints)到child上,本身挺簡(jiǎn)單的,可以被一些控件替換使用。Flutter的布局控件體系,梳理著發(fā)現(xiàn)確實(shí)有點(diǎn)亂,感覺(jué)總體思想是缺啥就造啥,哈哈。

3.2 布局行為

ConstrainedBox的布局行為非常簡(jiǎn)單,取決于設(shè)置的限制條件,而關(guān)于父子節(jié)點(diǎn)的限制因素生效優(yōu)先級(jí),可以查看之前的文章,在這里就不做具體敘述了。

3.3 繼承關(guān)系

Object > Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > SingleChildRenderObjectWidget > ConstrainedBox

ConstrainedBox也是一個(gè)基礎(chǔ)的布局控件。

3.4 示例代碼

new ConstrainedBox(  constraints: const BoxConstraints(    minWidth: 100.0,    minHeight: 100.0,    maxWidth: 150.0,    maxHeight: 150.0,  ),  child: new Container(    width: 200.0,    height: 200.0,    color: Colors.red,  ),);

例子也挺簡(jiǎn)單的,在一個(gè)寬高200.0的Container上添加一個(gè)約束最大最小寬高的ConstrainedBox,實(shí)際的顯示中,則是一個(gè)寬高為150.0的區(qū)域。

3.5 源碼解析

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

ConstrainedBox({Key key,@required this.constraints,Widget child})

包含了一個(gè)constraints屬性,且不能為null。

3.5.1 屬性解析

constraints:添加到child上的額外限制條件,其類(lèi)型為BoxConstraints。BoxConstraints的作用是干啥的呢?其實(shí)很簡(jiǎn)單,就是限制各種最大最小寬高。說(shuō)到這里插一句,double.infinity在widget布局的時(shí)候是合法的,也就說(shuō),例如想最大的擴(kuò)展寬度,可以將寬度值設(shè)為double.infinity。

3.5.2 源碼

@overrideRenderConstrainedBox createRenderObject(BuildContext context) {return new RenderConstrainedBox(additionalConstraints: constraints);}

RenderConstrainedBox實(shí)現(xiàn)其繪制。其具體的布局表現(xiàn)分兩種情況:

  • 如果child不為null,則將限制條件加在child上;
  • 如果child為null,則會(huì)盡可能的縮小尺寸。

具體代碼如下:

@overridevoid performLayout() {if (child != null) {  child.layout(_additionalConstraints.enforce(constraints), parentUsesSize: true);  size = child.size;} else {  size = _additionalConstraints.enforce(constraints).constrain(Size.zero);}}

3.6 使用場(chǎng)景

需要添加額外的約束條件可以使用此控件,例如設(shè)置最小寬高,盡可能的占用區(qū)域等等。筆者在實(shí)際開(kāi)發(fā)中使用的倒不是很多,倒不是說(shuō)這個(gè)控件不好使用,而是好多約束因素是綜合的,例如需要額外的設(shè)置margin、padding屬性能,因此單獨(dú)再套個(gè)這個(gè)就顯得很繁瑣了。

3.7 關(guān)于UnconstrainedBox

這個(gè)控件不做詳細(xì)介紹了,它跟ConstrainedBox相反,是不添加任何約束條件到child上,讓child按照其原始的尺寸渲染。

很神奇是吧,我也覺(jué)得,其實(shí)它的作用就是給child一個(gè)盡可能大的空間,不加約束的讓其顯示。用處我暫時(shí)木有想到。只能說(shuō)Flutter生產(chǎn)Widget很隨性。

4. 后話

筆者建的一個(gè)Flutter學(xué)習(xí)相關(guān)的項(xiàng)目,Github地址,里面包含了筆者寫(xiě)的關(guān)于Flutter學(xué)習(xí)相關(guān)的一些文章,會(huì)定期更新,也會(huì)上傳一些學(xué)習(xí)demo,歡迎大家關(guān)注。

5. 參考

  1. FittedBox class
  2. BoxFit enum
  3. AspectRatio class
  4. ConstrainedBox class
  5. BoxConstraints class
  6. UnconstrainedBox class
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Flutter之ConstrainedBox、SizedBox、UnconstrainedBox(尺寸限制類(lèi)容器)
[原創(chuàng)]一種Unity2D多分辨率屏幕適配方案
設(shè)計(jì)適應(yīng)不同屏幕分辨率的UI
display:flex 多欄多列布局
(翻譯)開(kāi)始iOS 7中自動(dòng)布局教程(二)
Xib、AutoLayout等使用心得
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服