创建边框半径为负的按钮并将其在Flutter中对齐 [英] Create buttons with negative border radius and align them in 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
类,您可以使用该类来构建按钮.然后,使用RawMaterialButton
和CustomPaint
小部件在您的应用程序中使用它.要定位和重叠元素,我将使用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;
}
}
更新:
我找到了另一个更优雅的解决方案来解决此问题.可以将CustomClipper
与ClipPath
小部件一起使用,而不是使用CustomPainter
.重要的是,按钮的ClipPath
和color
在RawMaterialButton
之外,只有这样,敲击按钮时的波纹效果与按钮本身的形状相同:
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屋!