Flutter——最详细Stack(堆叠布局)使用教程

本文详细介绍了Flutter中的Stack组件,用于在屏幕上堆叠多个子组件,并通过Alignment属性进行位置调整。同时讨论了Positioned组件,用于更精确地定位内部子组件,以及如何使用clipBehavior属性处理内容裁剪。此外,还提到了Align组件,它能方便地控制子组件的对齐方式。示例代码展示了不同属性设置下的布局效果。
摘要由CSDN通过智能技术生成

1.Stack简介:

可以容纳多个组件,以叠加的方式摆放子组件,后者居上。拥有Alignment属性,可以与Positioned组件联合使用,精准并有效摆放。同AndroidFramLayout布局相似。

属性作用
alignment子组件摆放的位置
clipBehavior剪辑小部件的内容
  • 使用场景:

比如开发中需要用户头像上面添加一个特殊标识,就需要是用到堆叠布局;

在这里插入图片描述

创建一个堆叠布局


class CustomStack extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var yellowBox = Container(
      color: Colors.yellow,
      height: 100,
      width: 100,
    );

    var redBox = Container(
      color: Colors.red,
      height: 90,
      width: 90,
    );

    var greenBox = Container(
      color: Colors.green,
      height: 80,
      width: 80,
    );

    return Container(
      width: 200,
      height: 120,
      color: Colors.grey.withAlpha(33),
      child: Stack(
        textDirection: TextDirection.rtl,
        fit: StackFit.loose,
        alignment: Alignment.topRight,
        children: <Widget>[yellowBox, redBox, greenBox],
      ),
    );
  }
}

在这里插入图片描述

属性Alignment.center

在这里插入图片描述

属性Alignment.bottomLeft

在这里插入图片描述

2.组件Positioned

精准堆叠布局内部,子组件的位置与排列;

属性作用
left向左距离
top向上距离
right向右距离
bottom向下距离
Stack(
        textDirection: TextDirection.rtl,
        fit: StackFit.loose,
        alignment: Alignment.bottomLeft,
        children: <Widget>[
          yellowBox,
          redBox,
          Positioned(
            bottom: 10,
            right: -30,
            child: greenBox,
          )
        ],
      )

在这里插入图片描述

可以看到绿色组件有一部分被裁剪调了,是因为没有使用clipBehavior属性,接下来我们来看Clip.none属性效果

属性clipBehavior: Clip.none

Stack(
        textDirection: TextDirection.rtl,
        fit: StackFit.loose,
        alignment: Alignment.bottomLeft,
        clipBehavior: Clip.none,
        children: <Widget>[
          yellowBox,
          redBox,
          Positioned(
            bottom: 10,
            right: -30,
            child: greenBox,
          )
        ],
      ),

加上该属性之后我们可以看到,绿色组件超出的部分也显示出来了。该属性的意义也就一目了然。

3.组件Align

精准控制子组件的位置,同Positioned相似。

创建一个带Align组件的样式

Stack(
        textDirection: TextDirection.rtl,
        fit: StackFit.loose,
        alignment: Alignment.bottomLeft,
        clipBehavior: Clip.none,
        children: <Widget>[
          Align(
            alignment: const Alignment(0, 0),
            child: redBox,
          ),
        ],
      )

在这里插入图片描述

可以看到该布局显示再正中间,Alignment(0, 0) 该属性分为 x 轴跟 y轴,范围值都是 -11 之间;

看Alignment(0, 1)
在这里插入图片描述

可以看到当y等于1时,红色组件排列再最底部;

看 Alignment(-0.5, -0.5)
在这里插入图片描述

当x等于 -0.5 时,很明显组件位于横轴-1到0的中间;
当y等于 -0.5 时,很明显组件位于主轴-1到0的中间;
总结x值的大小是根据横轴排列,y值的大小是根据主轴排列;

属性 Alignment(1, 4)
在这里插入图片描述

当x与y大于1时,子组件并没有被裁剪。说明使用Align属性并不受clipBehavior: Clip.none影响;

项目地址

https://github.com/z244370114/flutter_demo

你可以使用Flutter的动画库来实现带切换动画的横向堆叠头像列表。具体实现步骤如下: 1. 创建一个水平的ListView,用于展示头像列表。 2. 在ListView.builder()方法中,使用Stack堆叠头像。 3. 对于每个头像,使用Positioned来设置它在Stack中的位置。 4. 为了实现切换动画效果,你可以使用Flutter的动画库来创建一个AnimatedSwitcher Widget。当你想要更改当前显示的头像时,只需更改key值即可。 5. 在切换头像时,你可以使用Flutter的Tween动画类来实现缓慢的过渡效果。例如,你可以使用一个Tween<double>(begin: 0.0, end: 1.0)来控制头像的透明度,从而实现淡入淡出的效果。 下面是一个简单的示例代码,供参考: ``` class AvatarList extends StatefulWidget { @override _AvatarListState createState() => _AvatarListState(); } class _AvatarListState extends State<AvatarList> { int _currentIndex = 0; List<String> _avatars = [ "assets/avatar1.png", "assets/avatar2.png", "assets/avatar3.png", "assets/avatar4.png", ]; @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ AnimatedSwitcher( duration: Duration(milliseconds: 500), child: Image.asset( _avatars[_currentIndex], key: ValueKey<int>(_currentIndex), height: 100, width: 100, ), transitionBuilder: (Widget child, Animation<double> animation) { return FadeTransition( opacity: Tween<double>(begin: 0.0, end: 1.0).animate(animation), child: child, ); }, ), SizedBox(width: 20), Expanded( child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: _avatars.length, itemBuilder: (BuildContext context, int index) { return GestureDetector( onTap: () { setState(() { _currentIndex = index; }); }, child: Container( height: 80, width: 80, margin: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: _currentIndex == index ? Colors.blue : Colors.grey, width: 2, ), image: DecorationImage( image: AssetImage(_avatars[index]), fit: BoxFit.cover, ), ), ), ); }, ), ), ], ); } } ``` 在这个示例中,我们创建了一个AvatarList Widget,它包含一个水平的ListView和一个AnimatedSwitcher Widget。当用户点击头像列表中的某个头像时,我们使用setState()方法更新_currentIndex的值,从而实现切换头像的效果。同时,在AnimatedSwitcher中使用transitionBuilder属性来指定动画效果,这里我们使用了FadeTransition来实现淡入淡出的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怀君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值