【问题标题】:Flutter (Dart): Split the screen into 6 sections, each with one corner in the centerFlutter(Dart):将屏幕分成6个部分,每个部分中间有一个角
【发布时间】:2022-01-25 14:22:12
【问题描述】:

我正在尝试将屏幕分成 6 个部分/部分,满足以下要求:

  • 每个部分都应在屏幕中心有一个角(连接到示例图中的中心圆,见下文)。
  • 每个部分都应连接到屏幕的周边。

我想在每个部分都有一个单独的 GestureDetector。

有人知道使用 Flutter 和 Dart 的任何好方法吗?

示例图

【问题讨论】:

  • 你用cliper试过了吗?
  • 你是说flutter_custom_clippers吗?还是 ClipPath?
  • ClipPath 是你所需要的

标签: flutter dart flutter-layout


【解决方案1】:

对于内圈,我使用ContainerStack 来放置这些小部件。形状是使用ClipPath 制作的。

利用将圆形按钮放置为最后一个堆栈子项,因为 UI 优先考虑自下而上,

dartpad 上运行。

路径

class BottomCentertPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) => Path()
    ..moveTo(size.width / 4, size.height)
    ..lineTo(size.width / 4 * 3, size.height)
    ..lineTo(size.width / 2, size.height / 2);

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

class BottomLeftPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) => Path()
    ..moveTo(size.width, size.height / 3 * 2)
    ..lineTo(size.width, size.height)
    ..lineTo(size.width / 4 * 3, size.height)
    ..lineTo(size.width / 2, size.height / 2);

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

class BottomRightPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) => Path()
    ..moveTo(0, size.height / 3 * 2)
    ..lineTo(0, size.height)
    ..lineTo(size.width / 4, size.height)
    ..lineTo(size.width / 2, size.height / 2);

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

class CenterRighttPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) => Path()
    ..moveTo(size.width, size.height / 3)
    ..lineTo(size.width / 2, size.height / 2)
    ..lineTo(size.width, size.height / 3 * 2);

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

class CenterLeftPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) => Path()
    ..moveTo(0, size.height / 3)
    ..lineTo(size.width / 2, size.height / 2)
    ..lineTo(0, size.height / 3 * 2);

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

class TopRightPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) => Path()
    ..moveTo(size.width / 2, 0)
    ..lineTo(size.width, 0)
    ..lineTo(size.width, size.height / 3)
    ..lineTo(size.width / 2, size.height / 2);

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

class TopLeftPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) => Path()
    ..lineTo(size.width / 2, 0)
    ..lineTo(size.width / 2, size.height / 2)
    ..lineTo(0, size.height / 3);

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}

测试小部件


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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: LayoutBuilder(builder: (context, constraints) {
        return Stack(
          children: [
            GestureDetector(
              onTap: () {
                debugPrint("TopLeftPath:");
              },
              child: ClipPath(
                clipper: TopLeftPath(),
                child: Container(
                  color: Colors.cyanAccent,
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                debugPrint("TopRightPath:");
              },
              child: ClipPath(
                clipper: TopRightPath(),
                child: Container(
                  color: Colors.deepPurple,
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                debugPrint("CenterLeftPath:");
              },
              child: ClipPath(
                clipper: CenterLeftPath(),
                child: Container(
                  color: Colors.deepOrange,
                ),
              ),
            ),
            ClipPath(
              clipper: CenterRighttPath(),
              child: Container(
                color: Colors.greenAccent,
              ),
            ),
            GestureDetector(
              onTap: () {
                debugPrint("CenterRighttPath:");
              },
              child: ClipPath(
                clipper: CenterRighttPath(),
                child: Container(
                  color: Colors.greenAccent,
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                debugPrint("BottomRightPath");
              },
              child: ClipPath(
                clipper: BottomRightPath(),
                child: Container(
                  color: Colors.indigoAccent,
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                debugPrint("BottomCentertPath");
              },
              child: ClipPath(
                clipper: BottomCentertPath(),
                child: Container(
                  color: Colors.pinkAccent,
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                debugPrint("BottomLeftPath");
              },
              child: ClipPath(
                clipper: BottomLeftPath(),
                child: Container(
                  color: Colors.amberAccent,
                ),
              ),
            ),
            Align(
              alignment: Alignment.center,
              child: GestureDetector(
                onTap: () {
                  debugPrint("Center Widget");
                },
                child: Container(
                  height: constraints.maxWidth * .25,
                  decoration: const BoxDecoration(
                      shape: BoxShape.circle, color: Colors.white),
                ),
              ),
            )
          ],
        );
      }),
    );
  }
}

CustomClipper&lt;Path&gt; 上播放大小。查看this 了解更多信息。

结果

【讨论】:

  • 这太完美了,Yeasin,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2019-07-22
  • 2015-09-02
  • 1970-01-01
相关资源
最近更新 更多