Flutter - 如何为 Container 中的垂直 BorderRadius 添加边框?

Flutter - How can I add a border to vertical BorderRadius in Container?

我想实现下图中的效果。我只想在 Container 的顶部添加一个边框,该 Container 的 borderradius 内部带有 radialgradient。我怎样才能做到这一点? Looks like:

我这样试过:

Column(
  children: [
    const SizedBox(
      height: 300,
    ),
    Container(
      height: 400,
      width: double.infinity,
      decoration: const BoxDecoration(
        // The border in this section has no effect. How can I get it to be like in the picture?
        border: Border(
          top: BorderSide(color: Color(0XFFD9ECA7), width: 9.0),
        ),
        borderRadius: BorderRadius.vertical(
          top: Radius.elliptical(180, 90),
        ),
        gradient: RadialGradient(
          colors: [Color(0xFF730202), Color(0XFF6D7DC9)],
          center: Alignment(0.0, 1.9),
          radius: 1.9,
          stops: <double>[0.0, 0.9],
        ),
      ),
    ),
  ],
);

不太确定,但昨天偶然发现了这个,也许它可以帮助您找到正确的方向: 来自 flutter>lib>src>paintingbox_decoration.dart 文件

  /// The [shape] cannot be interpolated; animating between two [BoxDecoration]s
  /// with different [shape]s will result in a discontinuity in the rendering.
  /// To interpolate between two shapes, consider using [ShapeDecoration] and
  /// different [ShapeBorder]s; in particular, [CircleBorder] instead of
  /// [BoxShape.circle] and [RoundedRectangleBorder] instead of
  /// [BoxShape.rectangle].
  ///
  final BoxShape shape;

您可以使用 CustomPainter 和 CustomClipper 来达到您想要的效果。

Stack(
  children: [
    Container(
      color: const Color(0xFF191717),
      width: double.infinity,
      height: 300,
    ),
    ClipPath(
      clipper: CustomShape(),
      child: Container(
        height: 400,
        width: double.infinity,
        decoration: const BoxDecoration(
          gradient: RadialGradient(
            colors: [Color(0xFF730202), Color(0XFF6D7DC9)],
            center: Alignment(0.0, 1.9),
            radius: 1.9,
            stops: <double>[0.0, 0.9],
          ),
        ),
      ),
    ),
    CustomPaint(
      painter: CustomBorder(),
      child: Container(
        height: 400,
      ),
    ),
  ],
);

自定义形状:

  class CustomShape extends CustomClipper<Path> {
  @override
  getClip(Size size) {
    var path = Path();
    path.lineTo(0, size.height - 50);
    path.quadraticBezierTo(
        size.width / 2, size.height, size.width, size.height - 50);
    path.lineTo(size.width, 0);
    path.close();

    return path;
  }

  @override
  bool shouldReclip(CustomClipper oldClipper) {
    return true;
  }
}

自定义边框:

  class CustomBorder extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint();
    paint.color = const Color(0XFFD9ECA7);
    paint.style = PaintingStyle.stroke;
    paint.strokeWidth = 9;

    var path = Path();

    path.moveTo(0, size.height - 50);
    path.quadraticBezierTo(
        size.width / 2, size.height, size.width, size.height - 50);
    path.moveTo(size.width, 0);
    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}