颤振 - 剪辑路径

Posted

技术标签:

【中文标题】颤振 - 剪辑路径【英文标题】:Flutter - ClipPath 【发布时间】:2020-01-16 10:42:06 【问题描述】:

如何创建上述自定义的 clipPath 小部件? (我附上截图)

我试过了,但不是准确的输出

剪裁类

class MessageClipper extends CustomClipper<Path> 
  final double borderRadius = 15;
  @override
  Path getClip(Size size) 
    double width = size.width;
    double height = size.height;
    double rheight = height - height / 3;
    double oneThird = width / 3;

    final path = Path()
      ..lineTo(0, rheight - borderRadius)
      ..cubicTo(0, rheight - borderRadius, 0, rheight, borderRadius, rheight)
      ..lineTo(oneThird, rheight)
      ..lineTo(width/2-borderRadius, height-borderRadius)
      ..cubicTo(width / 2 - borderRadius, height - borderRadius, width / 2,
          height, width / 2 + borderRadius, height - borderRadius )
      ..lineTo(2 * oneThird, rheight)
      ..lineTo(width-borderRadius, rheight)
      ..cubicTo(width - borderRadius, rheight, width, rheight, width,
          rheight - borderRadius)
      ..lineTo(width, 0)
      ..lineTo(0, 0);
    return path;
  

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

我在这里调用了这个方法

Center(
        child: ClipPath(
        clipper: MessageClipper(),
    child: Container(
      height: 41.66,
      width: 91.63,
    decoration: BoxDecoration(
    borderRadius: BorderRadius.all(Radius.circular(16.0)),
    color: Colors.red,
    ),
    child:
    Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        Container(
          width: 7,
          height: 8,
          decoration: BoxDecoration(
              color: Color(0xFFCCCCCC),
              shape: BoxShape.circle),
        ),
        Container(
          width: 7,
          height: 8,
          decoration: BoxDecoration(
              color: Color(0xFFCCCCCC),
              shape: BoxShape.circle),
        ),
        Container(
          width: 7,
          height: 8,
          decoration: BoxDecoration(
              color: Color(0xFFCCCCCC),
              shape: BoxShape.circle),
        ),
        Container(
          width: 25,
          height: 24,
          decoration: BoxDecoration(
              color: Color(0xFF1287BA),
              shape: BoxShape.circle),
          child: Center(
            child: Text(
              "17",
              style: TextStyle(color: Color(0xFFFFFFFF)),
            ),
          ),
        ),
      ],

    ),
    ),)
    )

无法像这样CenterContainer 内的项目,

【问题讨论】:

在您的 pubspec.yaml 文件中添加 flutter_custom_clippers 作为依赖项 Refer this link 创建一个自定义的ShapeBorder 类 - 这样更容易获得好的结果 【参考方案1】:

使用这个简单的自定义ShapeBorder

class MessageBorder extends ShapeBorder 
  final bool usePadding;

  MessageBorder(this.usePadding = true);

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.only(bottom: usePadding? 20 : 0);

  @override
  Path getInnerPath(Rect rect, TextDirection textDirection) => null;

  @override
  Path getOuterPath(Rect rect, TextDirection textDirection) 
    rect = Rect.fromPoints(rect.topLeft, rect.bottomRight - Offset(0, 20));
    return Path()
      ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2)))
      ..moveTo(rect.bottomCenter.dx - 10, rect.bottomCenter.dy)
      ..relativeLineTo(10, 20)
      ..relativeLineTo(20, -20)
      ..close();
  

  @override
  void paint(Canvas canvas, Rect rect, TextDirection textDirection) 

  @override
  ShapeBorder scale(double t) => this;

还有那个使用代码:

Container(
  height: 64,
  decoration: ShapeDecoration(
    color: Colors.white,
    shape: MessageBorder(),
    shadows: [
      BoxShadow(color: Colors.black, blurRadius: 4.0, offset: Offset(2, 2)),
    ],
  ),
  alignment: Alignment.centerRight,
  padding: EdgeInsets.only(right: 8),
  child: Container(
    width: 30,
    decoration: BoxDecoration(
      color: Colors.blueAccent,
      shape: BoxShape.circle,
    ),
  ),
),

你可以得到这样的结果:

编辑:如果您希望您的 Widget 可点击,请使用以下内容:

class ButtonMessage extends StatelessWidget 
  final String text;
  final GestureTapCallback onTap;

  const ButtonMessage(this.text, this.onTap);

  @override
  Widget build(BuildContext context) 
    return Material(
      color: Colors.white,
      elevation: 4,
      clipBehavior: Clip.antiAlias,
      shape: MessageBorder(),
      child: InkWell(
        splashColor: Colors.orange,
        hoverColor: Colors.blueGrey,
        highlightColor: Colors.transparent,
        onTap: onTap,
        child: Container(
          height: 64,
          padding: EdgeInsets.only(bottom: 20, right: 8),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              Container(
                width: 7,
                height: 8,
                decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
              ),
              Container(width: 3,),
              Container(
                width: 7,
                height: 8,
                decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
              ),
              Container(width: 3,),
              Container(
                width: 7,
                height: 8,
                decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
              ),
              Container(width: 6,),
              Container(
                width: 25,
                height: 24,
                decoration: BoxDecoration(color: Color(0xFF1287BA), shape: BoxShape.circle),
                child: Center(
                  child: Text(text, style: TextStyle(color: Color(0xFFFFFFFF))),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  

EDIT2:带有自定义阴影的可点击气球:

class ButtonMessage extends StatelessWidget 
  final String text;
  final GestureTapCallback onTap;

  const ButtonMessage(this.text, this.onTap);

  @override
  Widget build(BuildContext context) 
    return Container(
      decoration: ShapeDecoration(
        shape: MessageBorder(usePadding: false),
        shadows: [
          BoxShadow(color: Colors.black, blurRadius: 4, offset: Offset(2, 2)),
        ],
      ),
      child: Material(
        color: Colors.white,
        clipBehavior: Clip.antiAlias,
        shape: MessageBorder(),
        child: InkWell(
          splashColor: Colors.orange,
          hoverColor: Colors.blueGrey,
          highlightColor: Colors.transparent,
          onTap: onTap,
          child: Container(
            height: 64,
            padding: EdgeInsets.only(bottom: 20, right: 8),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                Container(
                  width: 7,
                  height: 8,
                  decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
                ),
                Container(width: 3,),
                Container(
                  width: 7,
                  height: 8,
                  decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
                ),
                Container(width: 3,),
                Container(
                  width: 7,
                  height: 8,
                  decoration: BoxDecoration(color: Color(0xFFCCCCCC), shape: BoxShape.circle),
                ),
                Container(width: 6,),
                Container(
                  width: 25,
                  height: 24,
                  decoration: BoxDecoration(color: Color(0xFF1287BA), shape: BoxShape.circle),
                  child: Center(
                    child: Text(text, style: TextStyle(color: Color(0xFFFFFFFF))),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  

【讨论】:

我会检查并通知你...目前我移动了另一个项目。我今晚会检查并通知你 我添加了最终输出..我试图改变午睡的高度..但我做不到 height: 64, - 改变这个 我在我的问题上添加了您的结果,请检查 我需要改变午睡的高度(三角形高度)

以上是关于颤振 - 剪辑路径的主要内容,如果未能解决你的问题,请参考以下文章

如何将剪辑路径的文本相对于视口居中并显示所有剪辑路径的文本?

将具有混合(固定和百分比)值的 CSS 剪辑路径转换为 ​​SVG 剪辑路径

如何使用 CSS 剪辑路径剪辑画布?

剪辑路径宽度不是 100% 宽度

防止 CSS 剪辑路径剪辑儿童?

伪元素影响剪辑路径