0

OutlinedBorder我需要帮助了解如何使用类在 Flutter 中创建自定义形状。

我不想使用剪裁,因为我想测试自定义形状是否最好也不会剪裁按钮子项。

如果有人会使用更简单的形状进行解释,我会更喜欢,但这是我创建的:

在此处输入图像描述

它的效果很好,只有蓝色部分会对点击做出反应并且涟漪不会泄漏,但是有两颗星,我希望它只是一颗星。

这是我的代码:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'dart:math' as Math;

class StarShape extends OutlinedBorder {
  final BorderSide side;

  StarShape({
    this.side = const BorderSide(),
  });

  @override
  OutlinedBorder copyWith({BorderSide? side}) {
    return StarShape(side: side ?? const BorderSide());
  }

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.all(10);

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    var _path = Path()
      ..addRect(rect.deflate(25))
      ..close();
    return _path;
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    rect = rect.inflate(15);
    var mid = rect.width / 2;
    var min = Math.min(rect.width, rect.height);
    var half = min / 2;
    mid = mid - half;
    var path = Path();
// top left
    path.moveTo(mid + half * 0.5, half * 0.84);
// top right
    path.lineTo(mid + half * 1.5, half * 0.84);
// bottom left
    path.lineTo(mid + half * 0.68, half * 1.45);
// top tip
    path.lineTo(mid + half * 1.0, half * 0.5);
// bottom right
    path.lineTo(mid + half * 1.32, half * 1.45);
// top left
    path.lineTo(mid + half * 0.5, half * 0.84);
    return path;
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
    var mid = rect.width / 2;
    var min = Math.min(rect.width, rect.height);
    var half = min / 2;
    mid = mid - half;


    var path = Path();
// top left
    path.moveTo(mid + half * 0.5, half * 0.84);
// top right
    path.lineTo(mid + half * 1.5, half * 0.84);
// bottom left
    path.lineTo(mid + half * 0.68, half * 1.45);
// top tip
    path.lineTo(mid + half * 1.0, half * 0.5);
// bottom right
    path.lineTo(mid + half * 1.32, half * 1.45);
// top left
    path.lineTo(mid + half * 0.5, half * 0.84);
    canvas.drawPath(
      path,
      Paint()..color = Colors.amber,
    );
  }

  @override
  ShapeBorder scale(double t) {
    return this.scale(t);
  }
}
4

1 回答 1

0

有一个 SVG 到 CustomPaint 的转换器工具。你可以在这里找到它:https ://www.flutterclutter.dev/tools/svg-to-flutter-path-converter/

这是星形的代码:

class Star extends StatelessWidget {
  const Star({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: CustomPaint(size: Size(100, 100), painter: MyPainter()),
    );
  }
}

late Color waveColor;
late Size size;

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint();
    Path path = Path();

    // Path number 1

    paint.color = Colors.red;
    path = Path();
    path.lineTo(size.width * 0.19, size.height);
    path.cubicTo(size.width / 5, size.height * 0.96, size.width / 5,
        size.height * 0.92, size.width / 5, size.height * 0.88);
    path.cubicTo(size.width * 0.22, size.height * 0.8, size.width * 0.24,
        size.height * 0.73, size.width / 4, size.height * 0.65);
    path.cubicTo(size.width / 4, size.height * 0.64, size.width / 4,
        size.height * 0.63, size.width * 0.24, size.height * 0.63);
    path.cubicTo(size.width * 0.17, size.height * 0.55, size.width * 0.09,
        size.height * 0.47, size.width * 0.02, size.height * 0.4);
    path.cubicTo(size.width * 0.01, size.height * 0.39, size.width * 0.01,
        size.height * 0.39, 0, size.height * 0.38);
    path.cubicTo(size.width * 0.04, size.height * 0.38, size.width * 0.07,
        size.height * 0.37, size.width * 0.1, size.height * 0.37);
    path.cubicTo(size.width * 0.18, size.height * 0.36, size.width * 0.26,
        size.height * 0.34, size.width * 0.34, size.height / 3);
    path.cubicTo(size.width * 0.34, size.height / 3, size.width * 0.35,
        size.height * 0.32, size.width * 0.35, size.height * 0.32);
    path.cubicTo(size.width * 0.4, size.height * 0.22, size.width * 0.45,
        size.height * 0.12, size.width * 0.49, size.height * 0.02);
    path.cubicTo(size.width * 0.49, size.height * 0.01, size.width / 2,
        size.height * 0.01, size.width / 2, 0);
    path.cubicTo(size.width * 0.54, size.height * 0.08, size.width * 0.57,
        size.height * 0.16, size.width * 0.61, size.height * 0.24);
    path.cubicTo(size.width * 0.62, size.height * 0.26, size.width * 0.64,
        size.height * 0.29, size.width * 0.65, size.height * 0.32);
    path.cubicTo(size.width * 0.65, size.height * 0.32, size.width * 0.66,
        size.height / 3, size.width * 0.67, size.height / 3);
    path.cubicTo(size.width * 0.77, size.height * 0.35, size.width * 0.87,
        size.height * 0.36, size.width * 0.98, size.height * 0.38);
    path.cubicTo(size.width * 0.98, size.height * 0.38, size.width,
        size.height * 0.38, size.width, size.height * 0.39);
    path.cubicTo(size.width, size.height * 0.39, size.width, size.height * 0.39,
        size.width * 0.98, size.height * 0.4);
    path.cubicTo(size.width * 0.91, size.height * 0.47, size.width * 0.83,
        size.height * 0.55, size.width * 0.76, size.height * 0.63);
    path.cubicTo(size.width * 0.75, size.height * 0.63, size.width * 0.75,
        size.height * 0.64, size.width * 0.75, size.height * 0.65);
    path.cubicTo(size.width * 0.77, size.height * 0.77, size.width * 0.79,
        size.height * 0.88, size.width * 0.81, size.height);
    path.cubicTo(size.width * 0.81, size.height, size.width * 0.81, size.height,
        size.width * 0.81, size.height);
    path.cubicTo(size.width * 0.8, size.height, size.width * 0.79, size.height,
        size.width * 0.79, size.height);
    path.cubicTo(size.width * 0.7, size.height * 0.94, size.width * 0.6,
        size.height * 0.89, size.width * 0.51, size.height * 0.84);
    path.cubicTo(size.width / 2, size.height * 0.83, size.width / 2,
        size.height * 0.83, size.width * 0.49, size.height * 0.84);
    path.cubicTo(size.width * 0.4, size.height * 0.89, size.width * 0.3,
        size.height * 0.94, size.width / 5, size.height);
    path.cubicTo(size.width / 5, size.height, size.width / 5, size.height,
        size.width * 0.19, size.height);
    path.cubicTo(size.width * 0.19, size.height, size.width * 0.19, size.height,
        size.width * 0.19, size.height);
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
于 2021-09-26T13:26:24.933 回答