You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何实现仅边角带边框的Container自定义形状

Flutter实现Container仅四个边角带边框效果

你可以通过自定义CustomPaint绘制或者Stack堆叠边角装饰两种方式实现需求,以下是两种方案的具体实现:

方案1:自定义CustomPainter实现(推荐,灵活性高)

该方案可以自由调整边框粗细、边角长度、圆角大小、颜色等参数,适配性更强。
完整代码示例:

import 'package:flutter/material.dart';

class CornerBorderPainter extends CustomPainter {
  // 可自定义参数
  final Color borderColor;
  final double borderWidth;
  final double cornerLength; // 每个边角的边框长度
  final double borderRadius;

  CornerBorderPainter({
    required this.borderColor,
    required this.borderWidth,
    required this.cornerLength,
    required this.borderRadius,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = borderWidth;

    final r = Radius.circular(borderRadius);
    // 左上角
    Path topLeftPath = Path()
      ..moveTo(0, cornerLength + borderRadius.x)
      ..lineTo(0, borderRadius.y)
      ..arcToPoint(Offset(borderRadius.x, 0), radius: r)
      ..lineTo(cornerLength + borderRadius.x, 0);
    canvas.drawPath(topLeftPath, paint);

    // 右上角
    Path topRightPath = Path()
      ..moveTo(size.width - cornerLength - borderRadius.x, 0)
      ..lineTo(size.width - borderRadius.x, 0)
      ..arcToPoint(Offset(size.width, borderRadius.y), radius: r)
      ..lineTo(size.width, cornerLength + borderRadius.y);
    canvas.drawPath(topRightPath, paint);

    // 右下角
    Path bottomRightPath = Path()
      ..moveTo(size.width, size.height - cornerLength - borderRadius.y)
      ..lineTo(size.width, size.height - borderRadius.y)
      ..arcToPoint(Offset(size.width - borderRadius.x, size.height), radius: r)
      ..lineTo(size.width - cornerLength - borderRadius.x, size.height);
    canvas.drawPath(bottomRightPath, paint);

    // 左下角
    Path bottomLeftPath = Path()
      ..moveTo(cornerLength + borderRadius.x, size.height)
      ..lineTo(borderRadius.x, size.height)
      ..arcToPoint(Offset(0, size.height - borderRadius.y), radius: r)
      ..lineTo(0, size.height - cornerLength - borderRadius.y);
    canvas.drawPath(bottomLeftPath, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

// 使用示例
class CornerBorderContainer extends StatelessWidget {
  const CornerBorderContainer({super.key});

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: CornerBorderPainter(
        borderColor: Colors.white,
        borderWidth: 2,
        cornerLength: 20, // 可调整边角边框的长度
        borderRadius: 18,
      ),
      child: Container(
        width: 200,
        height: 100,
        decoration: BoxDecoration(
          color: Colors.red,
          borderRadius: BorderRadius.circular(18),
        ),
        child: const Center(
          child: Text(
            'Monday',
            style: TextStyle(
              color: Colors.white,
              fontSize: 30,
            ),
          ),
        ),
      ),
    );
  }
}

方案2:Stack堆叠实现(代码简单)

如果不想自定义绘制,可以直接在Stack里放四个边角的小装饰容器,适合快速实现:

class StackCornerBorderContainer extends StatelessWidget {
  const StackCornerBorderContainer({super.key});

  @override
  Widget build(BuildContext context) {
    const borderWidth = 2.0;
    const cornerLength = 20.0;
    const borderRadius = 18.0;

    return Stack(
      children: [
        // 底层主体Container
        Container(
          width: 200,
          height: 100,
          decoration: BoxDecoration(
            color: Colors.red,
            borderRadius: BorderRadius.circular(borderRadius),
          ),
          child: const Center(
            child: Text(
              'Monday',
              style: TextStyle(
                color: Colors.white,
                fontSize: 30,
              ),
            ),
          ),
        ),
        // 左上角装饰
        Positioned(
          top: 0,
          left: 0,
          child: Container(
            width: cornerLength + borderRadius,
            height: cornerLength + borderRadius,
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.only(topLeft: Radius.circular(borderRadius)),
              border: Border(
                top: BorderSide(color: Colors.white, width: borderWidth),
                left: BorderSide(color: Colors.white, width: borderWidth),
              ),
            ),
          ),
        ),
        // 右上角装饰
        Positioned(
          top: 0,
          right: 0,
          child: Container(
            width: cornerLength + borderRadius,
            height: cornerLength + borderRadius,
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.only(topRight: Radius.circular(borderRadius)),
              border: Border(
                top: BorderSide(color: Colors.white, width: borderWidth),
                right: BorderSide(color: Colors.white, width: borderWidth),
              ),
            ),
          ),
        ),
        // 右下角装饰
        Positioned(
          bottom: 0,
          right: 0,
          child: Container(
            width: cornerLength + borderRadius,
            height: cornerLength + borderRadius,
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.only(bottomRight: Radius.circular(borderRadius)),
              border: Border(
                bottom: BorderSide(color: Colors.white, width: borderWidth),
                right: BorderSide(color: Colors.white, width: borderWidth),
              ),
            ),
          ),
        ),
        // 左下角装饰
        Positioned(
          bottom: 0,
          left: 0,
          child: Container(
            width: cornerLength + borderRadius,
            height: cornerLength + borderRadius,
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(borderRadius)),
              border: Border(
                bottom: BorderSide(color: Colors.white, width: borderWidth),
                left: BorderSide(color: Colors.white, width: borderWidth),
              ),
            ),
          ),
        ),
      ],
    );
  }
}

两种方案都可以实现你要的四个边角带边框的效果,根据自己的开发需求选择即可。

内容的提问来源于stack exchange,提问作者Millenial2020

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:36:03