【问题标题】:Create buttons with negative border radius and align them in Flutter创建具有负边框半径的按钮并在 Flutter 中对齐它们
【发布时间】:2020-03-24 15:14:28
【问题描述】:

我想构建一个这样的布局

其中两个外部元素是按钮,而内部元素是 TextField。

如何在 Flutter 中创建这样的布局?

我的想法是使用绝对位置来对齐每个元素的左侧并使用高度来处理重叠,但我不确定这是最好的方法,我不知道如何创建按钮。

【问题讨论】:

    标签: android flutter


    【解决方案1】:

    我会使用 CustomPainter 类,您可以使用它来构建按钮。然后您使用RawMaterialButtonCustomPaint 小部件在您的应用程序中使用它。要定位和重叠元素,我会使用 Stack 小部件。

    附上您看到的外部右侧按钮的示例:

    
    ...
    body: Center(
      child: RawMaterialButton(
        onPressed: () {},
        child: CustomPaint(
          painter: ButtonShape(
            strokeColor: Colors.blue,
            strokeWidth: 1,
            paintingStyle: PaintingStyle.fill,
          ),
          child: Container(
            child: Center(
              child: Text('+', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 36)),
            ),
            height: 50,
            width: 150,
          ),
        ),
      ),
    ),
    ...
    
    
    class ButtonShape extends CustomPainter {
      final Color strokeColor;
      final PaintingStyle paintingStyle;
      final double strokeWidth;
    
      ButtonShape({this.strokeColor = Colors.black, this.strokeWidth = 3, this.paintingStyle = PaintingStyle.stroke});
    
      @override
      void paint(Canvas canvas, Size size) {
        Paint paint = Paint()
          ..color = strokeColor
          ..strokeWidth = strokeWidth
          ..style = paintingStyle;
    
        canvas.drawPath(shapePath(size.width, size.height), paint);
      }
    
      Path shapePath(double x, double y) {
        return Path()
          ..moveTo(0, 0)
          ..cubicTo(x/2, 0, x/2, y, 0, y)
          ..cubicTo(x, y, x, 0, 0, 0);
      }
    
      @override
      bool shouldRepaint(ButtonShape oldDelegate) {
        return oldDelegate.strokeColor != strokeColor ||
            oldDelegate.paintingStyle != paintingStyle ||
            oldDelegate.strokeWidth != strokeWidth;
      }
    }
    

    更新: 我找到了另一个更优雅的解决方案来解决这个问题。您可以将CustomClipperClipPath 小部件一起使用,而不是使用CustomPainter。重要的是,按钮的ClipPathcolorRawMaterialButton之外,只有这样,点击按钮的涟漪效果与按钮本身的形状相同:

    ...
    body Center(
      child: ClipPath(
        clipper: ButtonClipper(),
        child: Container(
          color: Colors.blue,
          child: RawMaterialButton(
            onPressed: () {},
            child: Container(
              height: 50,
              width: 150,
              child: Center(
                child: Text('+', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 36)),
              ),
            ),
          ),
        ),
      ),
    ),
    ...
    
    class ButtonClipper extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        final path = Path();
        path.moveTo(0, 0);
        path.cubicTo(size.width / 2, 0, size.width / 2, size.height, 0, size.height);
        path.cubicTo(size.width, size.height, size.width, 0, 0, 0);
        path.close();
        return path;
      }
    
      @override
      bool shouldReclip(ButtonClipper oldClipper) => false;
    }
    

    【讨论】:

    • 这很好,但是当我点击按钮时,波纹是矩形的并且在形状之外。如何更改它以使其与按钮的形状相匹配?
    • @matte_colo 我对 ClipPath 使用了一种新方法;查看我的更新答案
    猜你喜欢
    • 2018-10-04
    • 2023-01-16
    • 1970-01-01
    • 2020-03-14
    • 2021-10-01
    • 1970-01-01
    • 2020-10-16
    • 2021-01-20
    • 1970-01-01
    相关资源
    最近更新 更多