flutter 绘制右上角圆角三角形标签

文章介绍了如何在Flutter中使用CustomPainter创建一个自定义的LabelTopRightYellow组件,该组件能在右上角绘制带有弧形的标签,适用于特定场景的UI设计。

在这里插入图片描述
绘制:

import 'package:jade/utils/JadeColors.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;

class LabelTopRightYellow extends StatefulWidget {
  final String labelTitle; // 只能两个字的(文字偏移量没有根据文字长度改变)
  const LabelTopRightYellow({ this.labelTitle});
  
  State<StatefulWidget> createState() {
    return LabelViewState();
  }
}

class LabelViewState extends State<LabelTopRightYellow> with SingleTickerProviderStateMixin {

  
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: ArcPainter(labelTitle: widget.labelTitle),
      size: Size(35,35), // 调整大小以适应你的需求
    );
  }
}

class ArcPainter extends CustomPainter {

  //标签文字
  String labelTitle;
  ArcPainter({this.labelTitle});

  
  void paint(Canvas canvas, Size size) {
    double originX = 0.0 ;
    double originY = 0.0 ;

    double cx = size.width / 2;
    double cy = size.height / 2;
    Paint _paint = Paint()
      ..color = Color(0xffFFE50F)
      ..strokeWidth = 2
    //画笔是线段(默认是fill填充)
    /*..style = PaintingStyle.stroke*/;

    // canvas.drawCircle(Offset(cx,cy), 2, _paint);


    Path path = Path();
    // 绘制圆锥路径 权重越大路径越接近直角(不使用path.moveTo时,默认起点为左上角)
    path.conicTo(originX + size.width, originY, originX + size.width, originY+ size.height, 10);
    // 控制路径是否闭合,可不写
    path.close();
    canvas.drawPath(path, _paint);
    canvas.save();
    canvas.restore();

    TextPainter textPainterCenter = TextPainter(
      text: TextSpan(text: labelTitle, style: TextStyle(color: Color(0xff333333),fontSize: 10)),
      textDirection: TextDirection.ltr,
    );
    textPainterCenter.layout();
    canvas.rotate(math.pi / 4);
    canvas.translate(-math.pi , -((cy - math.pi)  * 2));
    textPainterCenter.paint(canvas, Offset(cx /*- textPainterCenter.size.width / 2*/,cy - textPainterCenter.size.height / 4));
    canvas.save();
    canvas.restore();
  }

  /// 度数转类似于π的那种角度
  double degToRad(double deg) => deg * (math.pi / 180.0);

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

引用:

Container(
	height: 180.w
      margin: EdgeInsets.symmetric(horizontal: 20.w),
      padding: EdgeInsets.only(left: 20.w),
      decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(8),
          boxShadow: [BoxShadow(color: JadeColors.grey_4,blurRadius: 2.0,offset: Offset(0.0, 0.0),)]
      ),
      child: Column(
        children: [
          _userView(),
          SizedBox(height: 20.w),
          _productView(),
          _countdownView()
        ],
      ),
    )
_userView(){
    return Stack(
      alignment: Alignment.topRight,
      children: [
        Row(
          children: [
            Container(
              width: 70.w,
              height: 70.w,
              margin: EdgeInsets.only(right: 20.w),
              child: Utils().roundedImage(PathConfig.testImageUrl[3], 70),
            ),
            Expanded(child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text('商户商户商户商户',style: TextStyle(fontSize: 30.sp,color: JadeColors.grey_2,fontWeight: FontWeight.w600),maxLines: 1,overflow: TextOverflow.ellipsis,),
                Text('10分钟前',style: TextStyle(fontSize: 22.sp,color: JadeColors.grey))
              ],
            ))
          ],
        ),
        LabelTopRightYellow(labelTitle: S.current.cuxiao,)
      ],
    );
  }
Flutter 中为图片设置 **部分圆角**(如仅左上角或右下角设置圆角)可以通过 `ClipRRect` 或 `RoundedRectangleBorder` 等方式实现。这种方式可以满足 UI 设计中对圆角的精细化控制需求。 ### 使用 `ClipRRect` 设置部分圆角 `ClipRRect` 提供了 `borderRadius` 属性,支持设置每个角的圆角半径值。通过 `BorderRadius.only()` 可以单独指定某个角的圆角半径。 ```dart ClipRRect( borderRadius: BorderRadius.only( topLeft: Radius.circular(20), bottomRight: Radius.circular(20), ), child: Image.network( "https://desk-fd.zol-img.com.cn/t_s960x600c5/g6/M00/03/0E/ChMkKWDZLXSICljFAC1U9uUHfekAARQfgG_oL0ALVUO515.jpg", width: 100, height: 100, fit: BoxFit.cover, ), ) ``` 该方式灵活度高,适用于需要对特定角进行圆角处理的场景[^3]。 --- ### 使用 `Container` 的 `decoration` 实现部分圆角 通过 `BoxDecoration` 的 `borderRadius` 属性,结合 `BorderRadius.only()`,也可以实现部分圆角效果。 ```dart Container( width: 100, height: 100, decoration: BoxDecoration( borderRadius: BorderRadius.only( topRight: Radius.circular(30), bottomLeft: Radius.circular(30), ), image: DecorationImage( image: AssetImage("images/landscape1.jpeg"), fit: BoxFit.cover, ), ), ) ``` 该方法适合将图片作为背景,并在其上叠加其他组件的场景[^4]。 --- ### 使用 `Card` 结合 `RoundedRectangleBorder` 设置部分圆角 虽然 `Card` 默认支持统一的圆角设置,但通过自定义 `shape` 属性,也可以实现部分圆角。 ```dart Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(25), bottomRight: Radius.circular(25), ), ), clipBehavior: Clip.antiAlias, child: Image.asset( "图片路径", width: 100, height: 100, fit: BoxFit.cover, ), ) ``` 此方式适用于需要结合 `Card` 样式进行部分圆角设计的组件[^2]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值