在堆栈的边界上颤动放置小部件

时间:2021-06-26 09:14:01

标签: flutter flutter-layout

我想达到这样的效果:

enter image description here

到目前为止,我的解决方案是为背景设置一个容器,该容器的子项是一个 Stack,它具有一个对齐的 Widget,使用 transform.translate 和 LayoutBuilder 偏移其宽度的一半。代码如下所示:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return IconOverlayTest();
  }
}
class IconOverlayTest extends StatelessWidget {
  const IconOverlayTest({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          width: 200,
          color: Colors.red,
          child: Stack(
            children: [
              Align(
                alignment: Alignment.centerRight,
                child: LayoutBuilder(
                  builder: (_, constraint) {
                    final _halfWidth = constraint.maxWidth / 2;
                    return Transform.translate(
                      offset: Offset(_halfWidth, 0),
                      child: Container(
                        padding: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                          color: Colors.white,
                          shape: BoxShape.circle,
                        ),
                        child: Icon(Icons.close),
                      ),
                    );
                  },
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

现在的问题是 Layoutbuilder 宽度选择了父容器的宽度,因此 _width 变为 100,所以我不确定如何将 LayoutBuilder 与 transform.translate 结合起来。对于这类问题,这甚至是一个好方法吗?我尝试在 Stack 内部使用定位,但这会切断红色背景之外的部分。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

    double iconSize = 35;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            centerTitle: true,
            title: Text('Drag widget on screen'),
          ),
          body: Container(
              width: 200,
              color: Colors.red,
              child: Stack(
                clipBehavior: Clip.none,
                children: [
                  Positioned(
                    left: 200-iconSize,
                    top: MediaQuery.of(context).size.height/2-(iconSize*1.5),
                    child: Container(
                            padding: EdgeInsets.all(10),
                            decoration: BoxDecoration(
                              color: Colors.white,
                              shape: BoxShape.circle,
                            ),
                            child: Icon(Icons.close, color:Colors.grey, size: iconSize),
                          ),
                  )
                ],
              ),
            ),
        );
  }