仅在颤动中的角落边框

Posted

技术标签:

【中文标题】仅在颤动中的角落边框【英文标题】:Border at corner only in flutter 【发布时间】:2021-06-09 05:58:58 【问题描述】:

我试图只在容器的角落制作边框。

Container(
  padding: const EdgeInsets.only(right: 8.0, left: 8.0),
  height: 60,
  child: Card(
    elevation: 2,
    shape: RoundedRectangleBorder(
        side: BorderSide(color: appThemeColor.shade200, width: 0.5),
        borderRadius: BorderRadius.circular(5)),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.end,
      children: <Widget>[
        Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.only(
                topRight: Radius.circular(15),
                bottomRight: Radius.circular(15)),
            color: Colors.deepPurple,
          ),
          width: 5,
        ),
      ],
    ),
  ),
)

【问题讨论】:

让我澄清一下。你想要像图片上那样画角吗? @SimonSot 只需要画角。 我明白了。这很容易通过CustomPaint 小部件完成。你想让我给你编码吗? @SimonSot 是的,我对自定义油漆了解不多。 【参考方案1】:

这可以通过将 CustomPainter 设置为 foregroundPainterCustomPaint 小部件来完成:

    import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'CustomPaint spotlight',
      home: Scaffold(
        appBar: AppBar(
          title: Text('CustomPaint spotlight'),
        ),
        body: Center(
          child: CustomPaint(
            foregroundPainter: BorderPainter(),
            child: Container(
              width: 200,
              height: 100,
              color: Colors.deepOrange[50],
            ),
          ),
        ),
      ),
    );
  


class BorderPainter extends CustomPainter 
  @override
  void paint(Canvas canvas, Size size) 
    double sh = size.height; // for convenient shortage
    double sw = size.width; // for convenient shortage
    double cornerSide = sh * 0.1; // desirable value for corners side

    Paint paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 1.5
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;

    Path path = Path()
      ..moveTo(cornerSide, 0)
      ..quadraticBezierTo(0, 0, 0, cornerSide)
      ..moveTo(0, sh - cornerSide)
      ..quadraticBezierTo(0, sh, cornerSide, sh)
      ..moveTo(sw - cornerSide, sh)
      ..quadraticBezierTo(sw, sh, sw, sh - cornerSide)
      ..moveTo(sw, cornerSide)
      ..quadraticBezierTo(sw, 0, sw - cornerSide, 0);

    canvas.drawPath(path, paint);
  

  @override
  bool shouldRepaint(BorderPainter oldDelegate) => false;

  @override
  bool shouldRebuildSemantics(BorderPainter oldDelegate) => false;

这会产生如下结果:

您需要知道 CustomPaint 不会裁剪其子角,并且在某些情况下可能会令人沮丧。你有两种方法可以解决这个问题:

简单的一个 - 在其子项上投射圆形边框并使其明显等于 CustomPaint 边框。

稳健的一个 - 用 ClipPath 用复制 CustomPaint 路径的路径包装孩子

    import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'CustomPaint spotlight',
      home: Scaffold(
        appBar: AppBar(
          title: Text('CustomPaint spotlight'),
        ),
        body: Center(
          child: CustomPaint(
            foregroundPainter: BorderPainter(),
            child: ClipPath(
              clipper: BorderClipper(),
              child: Container(
                width: 200,
                height: 100,
                color: Colors.deepOrange[50],
              ),
            ),
          ),
        ),
      ),
    );
  


class BorderPainter extends CustomPainter 
  @override
  void paint(Canvas canvas, Size size) 
    double sh = size.height; // for convenient shortage
    double sw = size.width; // for convenient shortage
    double cornerSide = sh * 0.1; // desirable value for corners side

    Paint paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 1.5
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;

    Path path = Path()
      ..moveTo(cornerSide, 0)
      ..quadraticBezierTo(0, 0, 0, cornerSide)
      ..moveTo(0, sh - cornerSide)
      ..quadraticBezierTo(0, sh, cornerSide, sh)
      ..moveTo(sw - cornerSide, sh)
      ..quadraticBezierTo(sw, sh, sw, sh - cornerSide)
      ..moveTo(sw, cornerSide)
      ..quadraticBezierTo(sw, 0, sw - cornerSide, 0);

    canvas.drawPath(path, paint);
  

  @override
  bool shouldRepaint(BorderPainter oldDelegate) => false;

  @override
  bool shouldRebuildSemantics(BorderPainter oldDelegate) => false;


class BorderClipper extends CustomClipper<Path> 
  @override
  Path getClip(Size size) 
    double sh = size.height; // for convenient shortage
    double sw = size.width; // for convenient shortage
    double cornerSide = sh * 0.1;

    Path path = Path()
      ..moveTo(cornerSide, 0)
      ..quadraticBezierTo(0, 0, 0, cornerSide)
      ..moveTo(0, sh - cornerSide)
      ..quadraticBezierTo(0, sh, cornerSide, sh)
      ..moveTo(sw - cornerSide, sh)
      ..quadraticBezierTo(sw, sh, sw, sh - cornerSide)
      ..moveTo(sw, cornerSide)
      ..quadraticBezierTo(sw, 0, sw - cornerSide, 0);
    return path;
  

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


【讨论】:

谢谢!为您解答。

以上是关于仅在颤动中的角落边框的主要内容,如果未能解决你的问题,请参考以下文章

如何仅在链接末尾弯曲链接的边框[重复]

颤动中的Textinputfield背景形状和浮动提示

div的弯曲角边框

如何在颤动的文本字段中处理标签文本? [关闭]

如何限制 UIPanGestureRecognizer 仅在角落工作

颤动 - 更改OutlineInputBorder的边框颜色