美文网首页
Flutter 组件之 Stack、Align、Position

Flutter 组件之 Stack、Align、Position

作者: Abner_XuanYuan | 来源:发表于2023-10-11 10:48 被阅读0次

1、Stack

Stack Stack({
  Key? key,
  //用于指定子控件的对齐方式,可以是左上角、居中、右下角等。
  AlignmentGeometry alignment = AlignmentDirectional.topStart,
  //子 Widget 的排列方式,默认值是 TextDirection.ltr。
  TextDirection? textDirection,
  //用于指定未定位子控件的大小调整方式,可以是填充、缩放或保持原始大小。
  StackFit fit = StackFit.loose,
  //剪辑小部件内容
  Clip clipBehavior = Clip.hardEdge,
  List<Widget> children = const <Widget>[],
})

示例

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Stack(
        alignment: Alignment.topLeft,
        children: [
          Container(
            width: 100,
            height: 100,
            color: Colors.red,
          ),
          const Text(
            "我是一段文字",
            style: TextStyle(fontSize: 30, color: Colors.green),
          )
        ],
      ),
    );
  }
}

2、Align

Align 组件可以调整子组件的位置 , Stack 组件中结合 Align 组件也可以控制每个子元素的显示位置。

Align Align({
  Key? key,
   //用于指定子控件的对齐方式.
  AlignmentGeometry alignment = Alignment.center,
  //指定子控件的宽度相对于父控件宽度的比例因子。取值范围为0.0到1.0。
  double? widthFactor,
  //指定子控件的高度相对于父控件高度的比例因子。取值范围为0.0到1.0。
  double? heightFactor,
  Widget? child,
})

示例

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: 200,
      color: Colors.lightBlue,
      child: const Align(
        // alignment: Alignment.center,
        alignment: Alignment(1, 1),
        child: FlutterLogo(
          size: 100,
        ),
      ),
    );
  }
}

Alignment Widget:
1、Alignment Widget 会以矩形的中心点作为坐标原点,即 Alignment(0.0, 0.0) 。
2、 x 的值从 -1 到 1 代表矩形左边到右边的距离,y 的值从 -1 到 1 代表矩形顶部到底边的距离,因此 2 个水平(或垂直)单位则等于矩形的宽(或高)。如 Alignment(-1.0, -1.0) 代表矩形的左侧顶点, Alignment(1.0, 1.0) 代表右侧底部终点, Alignment(1.0, -1.0) 则正是右侧顶点。
3、为了使用方便,矩形的原点、四个顶点,以及四条边的终点在 Alignment 类中都已经定义为了静态常量。
4、Alignment 可以通过其坐标转换公式将其坐标转为子元素的具体偏移坐标:

 //childWidth 为子元素的宽度, childHeight 为子元素高度。
(Alignment.x*childWidth/2+childWidth/2, Alignment.y*childHeight/2+childHeight/2)

5、Center 继承自 Align ,它比 Align 只少了一个 alignment 参数。由于 Align 的构造函数中
alignment 值为 Alignment.center ,所以,我们可以认为 Center 组件其实是对齐方式确定。

Align 结合 Stack 组件

///Align 结合 Stack 组件
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 300,
        width: 300,
        color: Colors.lightGreen,
        child: const Stack(
          alignment: Alignment.center,
          children: [
            Align(
              alignment: Alignment(1, -1),
              child: Icon(
                Icons.home,
                size: 40,
                color: Colors.white,
              ),
            ),
            Align(
              alignment: Alignment.center,
              child: Icon(
                Icons.search,
                size: 40,
                color: Colors.white,
              ),
            ),
            Align(
              alignment: Alignment.bottomRight,
              child: Icon(
                Icons.settings,
                size: 40,
                color: Colors.white,
              ),
            )
          ],
        ),
      ),
    );
  }
}

3、Positioned

Stack 组件中结合 Positioned 组件也可以控制每个子元素的显示位置。

Positioned Positioned({
  Key? key,
  //子元素距离左侧距离
  double? left,
  //子元素距离顶部的距离
  double? top,
  //子元素距离右侧距离
  double? right,
  //子元素距离底部的距离
  double? bottom,
  //组件的高度 (注意:宽度和高度必须是固定值,没法使用double.infinity)
  double? width,
  //子组件的高度
  double? height,
  required Widget child,
})

示例

///Positioned
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 200,
        height: 200,
        color: Colors.red,
        child: const Stack(
          // alignment: Alignment.center,
          children: [
            Positioned(
                left: 10,
                child: Icon(
                  Icons.home,
                  size: 40,
                  color: Colors.white,
                )),
            Positioned(
                bottom: 5,
                child: Icon(
                  Icons.search,
                  size: 40,
                  color: Colors.white,
                )),
            Positioned(
                right: 15,
                child: Icon(
                  Icons.settings,
                  size: 40,
                  color: Colors.white,
                )),
            Positioned(
                top: 20,
                child: Icon(
                  Icons.memory,
                  size: 40,
                  color: Colors.white,
                )),
          ],
        ),
      ),
    );
  }
}

Stack Positioned 案例

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  List<Widget> _customList() {
    List<Widget> list = [];
    for (var i = 0; i < 30; i++) {
      list.add(
        ListTile(
          title: Text("第 $i 个数据"),
        ),
      );
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    //获取屏幕的宽高
    final Size size = MediaQuery.sizeOf(context);

    return Stack(
      children: [
        ListView(
          padding: const EdgeInsets.only(top: 45),
          children: _customList(),
        ),
        Positioned(
            top: 0,
            left: 0,
            height: 40,
            width: size.width,
            child: Container(
              alignment: Alignment.center,
              color: Colors.black,
              child: const Text(
                "Hello Flutter",
                style: TextStyle(fontSize: 20, color: Colors.white),
              ),
            )),
      ],
    );
  }
}

补充:MediaQuery:获取屏幕宽度和高度

    final Size size = MediaQuery.of(context).size;
    print("宽: ${size.width} -- 高: ${size.height}");

相关文章

网友评论

      本文标题:Flutter 组件之 Stack、Align、Position

      本文链接:https://www.haomeiwen.com/subject/uqnoudtx.html