创建边框半径为负的按钮并将其在Flutter中对齐 [英] Create buttons with negative border radius and align them in Flutter

查看:80
本文介绍了创建边框半径为负的按钮并将其在Flutter中对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要构建这样的布局

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

Where the two external elements are buttons, while the inner one is a TextField.

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

How can I create a layout like this in Flutter?

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

My idea was to use absolute positions to align the left side of each element and to use elevation to handle overlapping but I'm not sure it's the best way and I don't know how to create the buttons.

推荐答案

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

I would use a CustomPainter class, with which you build the buttons. Then you use the RawMaterialButton and CustomPaint widget to use it in your application. To position and overlap the elements i would use the Stack widget.

在附件中,您可以看到外部右按钮的示例:

Attached you see an example of your outer right button:


...
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之外,只有这样,敲击按钮时的波纹效果与按钮本身的形状相同:

Update: I've found another, more elegant, solution to solve this. Instead of using a CustomPainter you can use a CustomClipper with the ClipPath widget. Important is, that the ClipPath and the color of the button is outside the RawMaterialButton, only then, the ripple effect on tapping the button is the same shape as the button itself:

...
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;
}

这篇关于创建边框半径为负的按钮并将其在Flutter中对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆