如何在Flutter中实现Curved Text(弧形文本)效果
Flutter实现弧形文本的方案
方法一:使用第三方包快速实现
可以直接用flutter_curved_text包快速搭建弧形文本,步骤如下:
- 在
pubspec.yaml中添加依赖:
dependencies: flutter_curved_text: ^0.3.0
- 简单使用示例:
import 'package:flutter/material.dart'; import 'package:flutter_curved_text/flutter_curved_text.dart'; class CurvedTextDemo extends StatelessWidget { const CurvedTextDemo({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: CurvedText( text: "这是一段弧形文本示例", style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.blue, ), radius: 150, startAngle: -120, endAngle: 120, direction: CurvedTextDirection.clockwise, ), ), ); } }
方法二:自定义CustomPaint实现(更灵活)
如果需要更精细的控制,可以通过CustomPaint手动绘制弧形文本,核心思路是将每个字符单独旋转并定位到圆弧上:
import 'package:flutter/material.dart'; class CustomCurvedText extends StatelessWidget { final String text; final TextStyle style; final double radius; final double startAngle; // 弧度值,比如-π/2对应90度向上 const CustomCurvedText({ super.key, required this.text, required this.style, required this.radius, this.startAngle = -0.5 * 3.1415926, }); @override Widget build(BuildContext context) { return CustomPaint( painter: _CurvedTextPainter( text: text, textStyle: style, radius: radius, startAngle: startAngle, ), size: Size(radius * 2, radius * 2), ); } } class _CurvedTextPainter extends CustomPainter { final String text; final TextStyle textStyle; final double radius; final double startAngle; _CurvedTextPainter({ required this.text, required this.textStyle, required this.radius, required this.startAngle, }); @override void paint(Canvas canvas, Size size) { final textSpan = TextSpan(text: text, style: textStyle); final textPainter = TextPainter( text: textSpan, textDirection: TextDirection.ltr, ); textPainter.layout(); // 计算每个字符的宽度总和,分配角度 double totalWidth = 0; for (int i = 0; i < text.length; i++) { final charSpan = TextSpan(text: text[i], style: textStyle); final charPainter = TextPainter( text: charSpan, textDirection: TextDirection.ltr, ); charPainter.layout(); totalWidth += charPainter.width; } // 总弧度(字符总宽度对应圆弧的弧度) final totalAngle = totalWidth / radius; final center = Offset(size.width / 2, size.height / 2); double currentAngle = startAngle; double currentX = center.dx + radius * cos(currentAngle); double currentY = center.dy + radius * sin(currentAngle); for (int i = 0; i < text.length; i++) { final char = text[i]; final charSpan = TextSpan(text: char, style: textStyle); final charPainter = TextPainter( text: charSpan, textDirection: TextDirection.ltr, ); charPainter.layout(); // 计算字符的旋转角度(垂直于圆弧切线) final charAngle = currentAngle + 0.5 * 3.1415926; canvas.save(); // 平移到字符位置,旋转后绘制 canvas.translate(currentX, currentY); canvas.rotate(charAngle); charPainter.paint(canvas, Offset(-charPainter.width / 2, -charPainter.height / 2)); canvas.restore(); // 更新下一个字符的角度和位置 final charWidth = charPainter.width; final angleStep = charWidth / radius; currentAngle += angleStep; currentX = center.dx + radius * cos(currentAngle); currentY = center.dy + radius * sin(currentAngle); } } @override bool shouldRepaint(covariant _CurvedTextPainter oldDelegate) { return text != oldDelegate.text || textStyle != oldDelegate.textStyle || radius != oldDelegate.radius || startAngle != oldDelegate.startAngle; } }
使用自定义组件的示例:
class CustomCurvedTextDemo extends StatelessWidget { const CustomCurvedTextDemo({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: CustomCurvedText( text: "自定义绘制的弧形文本", style: const TextStyle( fontSize: 18, color: Colors.red, fontWeight: FontWeight.w600, ), radius: 120, startAngle: -0.6 * 3.1415926, ), ), ); } }
以上两种方法都能实现你需要的弧形文本效果,第三方包适合快速开发,自定义绘制则能满足更多个性化需求。
内容的提问来源于stack exchange,提问作者Muhammad Zeeshan
相关产品推荐
相关产品推荐

