📜  Flutter Stack(1)

📅  最后修改于: 2023-12-03 14:41:15.510000             🧑  作者: Mango

Flutter Stack介绍

简介

Flutter中的Stack类似于一个堆栈,该堆栈中的部件可以叠放在一起。提供了一种让部件重叠的方法,这些部件可以通过一个无限数量的层层嵌套的方式进行一一摆放,以此来实现某些特殊的视觉效果,例如:层叠相册,叠放式的卡片布局等。Stack部件对于那些希望在相对位置上放置小部件而不是在相对位置上摆放大部件的情况非常有用。

基本用法

Flutter Stack部件包含多个子部件,用分层的方式进行渲染,首先添加的子部件在底部,后来的子部件会叠放在它们的上面,示例代码如下:

Stack(
  children: <Widget>[
    Container(
      width: 150,
      height: 150,
      color: Colors.red,
    ),
    Container(
      width: 120,
      height: 120,
      color: Colors.green,
    ),
    Container(
      width: 90,
      height: 90,
      color: Colors.blue,
    ),
  ],
)

这段代码显示了一个红色区域在最下面,一个绿色区域在红色区域上面,一个蓝色区域在绿色区域的顶部。在Stack类中每一个子组件都是一个层,并且每一层的位置、大小可以通过定位控件来实现。

Stack类的属性

| 属性 | 说明 | | --- | --- | | alignment | 阵列中的对齐方式 | | fit | 未定位的孩子应该如何重新调整自己 | | overflow | 旨在在Stack范围之外的孩子会如何被剪切 | | textDirection | 定位和子部件的顺序 |

Stack控件的对齐方式

在Stack部件中,子部件的位置是由其父Stack部件的对齐方式来决定的,以下为对齐方式的详细介绍。

Alignment.bottomCenter

子部件在底部中心对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.bottomCenter,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.bottomLeft

子部件在左下角对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.bottomLeft,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.bottomRight

子部件在右下角对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.bottomRight,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.center

子部件在中心对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.center,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.centerLeft

子部件在左边中心对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.centerLeft,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.centerRight

子部件在右边中心对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.centerRight,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.topCenter

子部件在顶部中心对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.topCenter,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.topLeft

子部件在左上角对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.topLeft,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Alignment.topRight

子部件在右上角对齐。

Container(
  color: Colors.redAccent,
  height: 200,
  width: 200,
  child: Stack(
    alignment: Alignment.topRight,
    children: <Widget>[
      Icon(Icons.access_alarms, color: Colors.black, size: 50),
    ],
  ),
),
Stack动画效果

Stack部件可以实现一些非常酷的动画效果,例如,当一个子部件从顶部滑入时,会将下方的部件推出,直到滑入的部分完全覆盖了下方的部件。示例代码如下:

class SlideAnimationWidget extends StatefulWidget {
  @override
  _SlideAnimationWidgetState createState() => _SlideAnimationWidgetState();
}

class _SlideAnimationWidgetState extends State<SlideAnimationWidget> with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation<Offset> _animation;

  @override
  void initState() {
    _animationController = AnimationController(vsync: this, duration: Duration(seconds: 1));
    _animation = Tween<Offset>(begin: Offset.zero, end: Offset(0, -1)).animate(_animationController);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Slide Animation"),
      ),
      body: Stack(
        children: [
          Container(
            color: Colors.blue,
          ),
          SlideTransition(
            position: _animation,
            child: Container(
              height: 200,
              width: MediaQuery.of(context).size.width,
              color: Colors.red,
              child: Center(
                child: Text(
                  "Swipe Up",
                  style: TextStyle(color: Colors.white, fontSize: 30),
                ),
              ),
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          if (_animationController.isCompleted) {
            _animationController.reverse();
          } else {
            _animationController.forward();
          }
        },
        child: Icon(Icons.swap_vert),
      ),
    );
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }
}

在这个例子中,我们在屏幕底部放置了一个红色的Container,相对的是一个与屏幕相同大小的蓝色Container。当我们在红色Container上滑动的时候,红色Container会向上滑出,并完全覆盖蓝色Container,直到整个红色Container完全显示出来。当我们下滑的时候,红色Container会回到原来的位置。这个动画的实现是通过使用SlideTransition,以偏移量的方式来控制红色Container的滑入和滑出。效果如下:

Slide Animation

结论

Stack部件可以让您非常轻松地在Flutter应用程序中创建出一些惊人的视觉效果,例如:层叠相册,叠放式的卡片布局等。通过堆栈方式的渲染,Stack部件可以让多个部件自由组合,以实现各种简单或复杂的布局需求。同时,Stack部件也开启了许多互动式动画效果的实现,例如:Slide Animation。不论是为用户呈现良好的UI法则,或是用于实现一些炫酷的交互动画,Stack部件都是一个非常不错的选择。