Flutter自定义Decoration实现特殊的背景框

我们常用的BoxDecoration可以实现这些功能

const BoxDecoration({
    this.color, // 底色
    this.image, // 图片
    this.border, 边色
    this.borderRadius, // 圆角度
    this.boxShadow, // 阴影
    this.gradient, // 渐变
    this.backgroundBlendMode, // 混合Mode
    this.shape = BoxShape.rectangle,  // 形状
  }) 

有些特殊的背景需要,比如:

 要实现上面的背景框,可以通过自定义decoration,通过canvas和painter实现,代码如下:

import 'package:flutter/material.dart';

class CustomDecoration extends Decoration {
  final double marginLeft;//顶角离左边的距离
  final Color lineColor;
  final double height;//顶角高度
  final double radius;//边框圆角大小
  CustomDecoration(
      {required this.marginLeft,
      this.radius = 8,
      this.lineColor = Colors.black,
      this.height = 16});
  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) {
    // TODO: implement createBoxPainter
    return _CustomPainter(this, marginLeft, lineColor, radius, height);
  }
}

class _CustomPainter extends BoxPainter {
  final CustomDecoration customDecoration;
  Paint? painter;
  final double marginLeft;
  final Color lineColor;
  final double height;
  final double radius;

  _CustomPainter(this.customDecoration, this.marginLeft, this.lineColor,
      this.radius, this.height)
      : painter = Paint()
          ..color = lineColor
          ..strokeWidth = 1
          ..style = PaintingStyle.stroke;

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    var size = configuration.size;
    Offset leftTop = offset;
    Offset rightTop = leftTop.translate(size!.width, 0);
    Offset leftBottom = leftTop.translate(0, size.height);
    Offset rightBottom = leftTop.translate(size.width, size.height);

    final leftStart = leftTop.translate(radius, 0); //点1
    final leftPoint = leftTop.translate(marginLeft, 0); //点2
    final topPoint = leftPoint.translate(height, -height); // 点3
    final rightPoint = leftPoint.translate(height*2, 0); // 点4
    final top5 = rightTop.translate(-radius, 0);
    final top6 = rightTop.translate(0, radius);
    final bottom7 = rightBottom.translate(0, -radius);
    final bottom8 = rightBottom.translate(-radius, 0);
    final bottom9 = leftBottom.translate(radius, 0);
    final bottom10 = leftBottom.translate(0, -radius);
    final top11 = leftTop.translate(0, radius);

    final path = Path()
      ..moveTo(leftStart.dx, leftStart.dy)
      ..lineTo(leftPoint.dx, leftPoint.dy)
      ..lineTo(topPoint.dx, topPoint.dy)
      ..lineTo(rightPoint.dx, rightPoint.dy)
      ..lineTo(top5.dx, top5.dy)
      ..arcToPoint(top6, radius: Radius.circular(radius))
      ..lineTo(bottom7.dx, bottom7.dy)
      ..arcToPoint(bottom8, radius: Radius.circular(radius))
      ..lineTo(bottom9.dx, bottom9.dy)
      ..arcToPoint(bottom10, radius: Radius.circular(radius))
      ..lineTo(top11.dx, top11.dy)
      ..arcToPoint(leftStart, radius: Radius.circular(radius));
 

    canvas.drawPath(path, painter!..style = PaintingStyle.stroke);
  }
}
OK,以上demo主要通过canvas的drawPath方法直接路径绘制出来,也可以按照这个思路绘制其他复杂的边框。此实例仅供参考!
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值