Flutter Widget 之 Stack(层叠布局)

Flutter中的层叠布局 Stack 与Android的FrameLayout相似。子控件是相对于父布局放置的,运行子控件堆叠起来。

1. Stack构造方法:

 Stack({
    Key key,
    this.alignment = AlignmentDirectional.topStart,
    this.textDirection,
    this.fit = StackFit.loose,
    this.overflow = Overflow.clip,
    List<Widget> children = const <Widget>[],
  }) : super(key: key, children: children);

2. Stack属性:

- alignment:

此参数是子控件的对齐方式,默认是AlignmentDirectional.topLeft (左上)。

- textDirection:

子组件排列方向,可选值有:
TextDirection.ltr:从左往右排列。
TextDirection.rtl:从右往左排列

- fit:

用来决定没有Positioned方式时候子Widget的大小,StackFit.loose 指的是子Widget 多大就多大,
StackFit.expand使子Widget的大小和父组件一样大

- overflow:

此属性决定如何显示超出Stack显示空间的子组件;值为Overflow.clip时,超出部分会被剪裁(隐藏),
值为Overflow.visible 时则不会。
import 'package:flutter/material.dart';

class StackPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stack Page'),
      ),
      body: _stackWidget(),
    );
  }

  Widget _stackWidget() {
    return Stack(
      children: <Widget>[
        Container(
          width: 100,
          height: 100,
          color: Colors.red,
        ),
        Container(
          width: 90,
          height: 90,
          color: Colors.blue,
        ),
        Container(
          width: 80,
          height: 80,
          color: Colors.green,
        ),
      ],
    );
  }
}

效果如下:

在这里插入图片描述

如果加入属性 alignment: AlignmentDirectional.bottomEnd, 效果如下:

在这里插入图片描述

AlignmentDirectional支持坐标定位,例如添加:AlignmentDirectional(6, 6),效果如下:

在这里插入图片描述
设置属性 fit: StackFit.expand, 最后一个子控件会撑满整个Stack,如下:

在这里插入图片描述
最后一个子控件是绿色的,所以绿色的就占满了整个Stack,虽然设置了宽高都是80,但是已经没有效果了。

3. Positioned

用来在Stack中辅助子控件定位的组件,一般在子控件超过3个时使用。

 const Positioned({
    Key key,
    this.left,
    this.top,
    this.right,
    this.bottom,
    this.width,
    this.height,
    @required Widget child,
  })

left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离。

 Widget _positionedWidget() {
    return Stack(
      children: <Widget>[
        Positioned(
          top: 100,
          child: Container(
            color: Colors.green,
            child: Text('子控件1'),
          ),
        ),
        Positioned(
          top: 200,
          right: 100,
          child: Container(
            color: Colors.red,
            child: Text('子控件2'),
          ),
        ),
        Positioned(
          left: 100,
          child: Container(
            color: Colors.blue,
            child: Text('子控件3'),
          ),
        ),
      ],
    );
  }

效果如下:
在这里插入图片描述

Widget _positionedWidget() {
    return Stack(
      children: <Widget>[
        Positioned.fill(
          child: Container(
            color: Colors.grey,
          ),
        ),
        Positioned(
          top: 100,
          left: 0,
          right: 0,
          child: Container(
            color: Colors.green,
            child: Text('子控件1'),
          ),
        ),
        Positioned(
          top: 200,
          right: 100,
          child: Container(
            color: Colors.red,
            child: Text('子控件2'),
          ),
        ),
        Positioned(
          bottom: 0,
          right: 0,
          left: 0,
          child: Container(
            color: Colors.blue,
            child: Text('子控件3'),
          ),
        ),
      ],
    );
  }

在这里插入图片描述

4. 实现一个头像布局

import 'package:flutter/material.dart';

class StackPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stack Page'),
      ),
      body: _headStack(),
    )

Widget _headStack() {
    return Stack(
      alignment: Alignment.bottomCenter,
//      alignment: FractionalOffset(0.5, 0.89),
      children: <Widget>[
        Positioned(
          child: CircleAvatar(
            backgroundImage: NetworkImage(
                'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1431065488,2677808608&fm=26&gp=0.jpg'),
            radius: 100,
          ),
        ),
        Positioned(
          bottom: 20,
          child: Container(child: new Text('NickName')),
        ),
      ],
    );
  }
}

效果如下图:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值