【问题标题】:Flutter - Trying to achieve this complex layoutFlutter - 试图实现这种复杂的布局
【发布时间】:2020-03-05 22:12:15
【问题描述】:

我正在尝试实现以下Flutter布局(如图)。

我想并排放置两个图像,我知道使用 Row 可以轻松实现,但我想要的是通过形状将两个图像分开(如图所示)。另外,我知道使用 CustomClipper,但我想不出一种方法来实现。

如果有人可以帮助我,我将不胜感激。提前致谢。

【问题讨论】:

    标签: flutter flutter-layout clipper


    【解决方案1】:

    您可以按以下顺序将stack 用于第 I 部分和 3 个孩子: - 你的迅雷(或任何你喜欢的路径)颜色的容器 - 区域 I 的第一张图片 - 区域 II 的第二张图片

    用特定的CustomClipper<Path> 将每个图像包装成一个ClipPath:目标是将图像剪辑到应该显示的一侧使用与另一个剪辑器“填充” .在中间,您将有一个没有图像被剪切的区域,因此将显示堆栈中的第一个小部件。

    这里是完整的源代码:

    import 'package:flutter/material.dart';
    
    main() async {
      runApp(
        MaterialApp(
          home: Scaffold(body: ComplexLayoutApp()),
        ),
      );
    }
    
    class ComplexLayoutApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Column(children: [
          Expanded(child: Part1()),
          Expanded(child: Part2()),
        ]);
      }
    }
    
    class Part1 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Stack(fit: StackFit.expand, children: [
          Container(
            color: Colors.black87,
          ),
          ClipPath(
            clipper: Area1CustomClipper(),
              child: Image.network(
                'https://picsum.photos/seed/area1/400/100',
                fit: BoxFit.fill,
              )),
          ClipPath(
              clipper: Area2CustomClipper(),
              child: Image.network(
                'https://picsum.photos/400/300',
                fit: BoxFit.fill,
              ))
        ]);
      }
    }
    
    class Part2 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Center(child: Text("Part II")),
          ],
        );
      }
    }
    
    const double offset = 0.34;
    
    class Area1CustomClipper extends CustomClipper<Path> {
    
      @override
      Path getClip(Size size) {
        Path path = Path();
    
        path.moveTo(4*size.width/8, 0);
        path.lineTo((4-offset)*size.width/8, (4)*size.height/8);
        path.lineTo((4)*size.width/8, (4)*size.height/8);
        path.lineTo(size.width/2, size.height);
    
        path.lineTo(0, size.height);
        path.lineTo(0, 0);
        path.close();
        return path;
      }
    
      @override
      bool shouldReclip(CustomClipper<Path> oldClipper) => false;
    }
    
    class Area2CustomClipper extends CustomClipper<Path> {
    
      @override
      Path getClip(Size size) {
        Path path = Path();
    
        path.moveTo(4*size.width/8, 0);
        path.lineTo((4)*size.width/8, (4-offset)*size.height/8);
        path.lineTo((4+offset)*size.width/8, (4 - offset)*size.height/8);
        path.lineTo(size.width/2, size.height);
    
        path.lineTo(size.width, size.height);
        path.lineTo(size.width, 0);
        path.close();
        return path;
      }
    
      @override
      bool shouldReclip(CustomClipper<Path> oldClipper) => false;
    }
    

    它会生成以下 UI:

    【讨论】:

    • 非常感谢您,先生。你做了出色的工作。我对此表示高度赞赏和尊重。我对您提供的解决方案感到满意,我什至会使用它。但是,我想知道我是否可以实现与我在问题图片中绘制的相同的布局。这可能吗?谢谢你。
    • 我的方案和你画的布局有什么区别?
    • 请查看此图片以了解输出i.imgur.com/MO3CU1N.jpg的差异@
    • 好的 :-D 根据需要更改每个裁剪器的路径
    • 嗯,是的 :P 我正在尝试找出路径 :p 如果你知道,请告诉我。谢谢
    猜你喜欢
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 2020-09-06
    • 2020-05-30
    • 1970-01-01
    相关资源
    最近更新 更多