LOADING

加载过慢请开启缓存,浏览器默认开启

flutter之层叠布局

2023/6/5
flutter flutter overlap

层叠布局

层叠布局类似于H5中的绝对定位,主要利用StackPositioned完成.Stack表示使用层叠布局,并设置未定位组件的默认位置AligmentDirectional.topStart,而Positioned指示子组件如何定位.

Stack

  1. textDirection 与前面学习的RowColumn相同,表示组件起始位置,同时也是aligment的参考点.
  2. aligment,默认值为AligmentDirectional.topStart,当某一子组件缺省定位的话,将使用该属性
  3. fit,指示没有定位的子组件如何确定自身大小,Fit.loose表示使用子组件自身大小,Fit.expand表示最大化子组件到Stack的大小
  4. clipBehavior,如果子组件超出Stack,应当如何裁剪
ConstrainedBox(
    constraints:BoxConstraints.expand(),
    child:Stack(
        textDirection:TextDirection.ltr,
        aligment:AligmentDirectional.center,
        fit:Fit.expand,
        clipBehavior:Clip.hardEdge,
        children:[
            Positioned(
                child:Text("first widget"),
                top:20
            ),
            Container(
                color:Colors.red,
                width:200,
                height:200
            ),
            Positioned(
                child:Text("third widget"),
                left:20
            )
        ]
    )
)

以上代码将渲染一个全屏背景为红色第二个组件,以及一个 third widget的文本,为什么?

  1. 即使我们指定了Container的宽高度,但由于我们在Stack上指定了Fit.expand以撑开子组件为Stack最大宽高度.而Container并未指定位置,所以将显示一个全屏的红色.
  2. 由于Stack是层叠布局,所以第一个元素将被全屏的Container所遮盖,即第一个子组件实际上在Container下层.
  3. 我们只给第三个Positioned指定了left属性,并未指定top/bottom,所以是没法定位的,这时使用了Stackaligment属性,所以该组件将在屏幕中央距离左侧20的位置显示.

Positioned

positioned组件较为简单,其中toprightbottomleft分别代表四个方位,而widthheight则表示定位元素的宽高度,并且会覆盖元素所定义的宽高度.但是要注意,这两个属性还要参与配合toprightbottomleft进行定位.比如,我们不能同时指定水平方向的leftrightwidth.因为当我们指定了leftright后,宽度其实已经算出来了,举一反三,当我们同时指任意两个属性时,第三个属性已经算出来,再指定,必然会报错.垂直方向同理.

Positioned(
    left:10,
    top:10,
    width:100,
    height:100,
    child:Container(
        color:Colors.blue[200]
    )
)

上面我们提到,widthheight会确认自组件的大小,并覆盖掉子组件设置的宽高度.如果我们就想用子组件的呢?肯定是掏出我们在布局约束与原理中学到的unconstrinedBox啦,不过要注意, unconstrainedBox只是不会将约束透传给子组件,其自身还是受到Positioned大小的影响滴.