在Flutter中,我试着在一个数字周围做一个分段环(或径向量规)来指示它的值。链接中的例子本身已经是一个解决方案,但是,我读到syncfusion小部件不是免费的。(我正在商业上使用它)任何替代方案或想法如何将其付诸实践?
ecfsfe2w1#
您可以使用CustomPainter来实现相同的目的,
CustomPainter
class RingPainter extends CustomPainter { const RingPainter({ required this.percentage, this.startColor, this.endColor, this.width, }) : assert(percentage >= 0 && percentage <= 100, "Percentage must be in the range 0-100!"); final double percentage; final Color? startColor; final Color? endColor; final double? width; double get progress => percentage / 100; @override void paint(Canvas canvas, Size size) { var angle = math.pi / 180 * 230; canvas.rotateAroundCenter(size, angle); canvas.drawRing( size, 1, startColor: Colors.black12, endColor: Colors.black12, width: width, ); canvas.drawRing( size, progress, startColor: startColor, endColor: endColor, width: width, ); } @override bool shouldRepaint(CustomPainter oldDelegate) => false; } extension on Canvas { rotateAroundCenter(Size size, double angleInRadians) { final double r = math.sqrt(size.width * size.width + size.height * size.height) / 2; final alpha = math.atan(size.height / size.width); final beta = alpha + angleInRadians; final shiftY = r * math.sin(beta); final shiftX = r * math.cos(beta); final translateX = size.width / 2 - shiftX; final translateY = size.height / 2 - shiftY; translate(translateX, translateY); rotate(angleInRadians); } drawRing( Size size, double value, { Color? startColor, Color? endColor, double? width, }) { final rect = Rect.fromLTWH(-15, 0.0, size.width, size.height); final gradient = SweepGradient( startAngle: 3 * math.pi / 2, endAngle: 7 * math.pi / 2, tileMode: TileMode.repeated, colors: [ startColor ?? Colors.pink, endColor ?? Colors.blueAccent, ], ); final paint = Paint() ..shader = gradient.createShader(rect) ..strokeCap = StrokeCap.round ..style = PaintingStyle.stroke ..strokeWidth = width ?? 24; final center = Offset(size.width / 2, size.height / 2); final radius = math.min(size.width / 2, size.height / 2) - ((width ?? 24) / 2); const startAngle = -math.pi / 2; final sweepAngle = 2 * math.pi * value * 0.723; drawArc( Rect.fromCircle(center: center, radius: radius), startAngle, sweepAngle, false, paint, ); } }
将其与CustomPaint小工具配合使用,
CustomPaint
CustomPaint( painter: RingPainter( percentage: 70, width: 20, ), )
如果你想在戒指里写文字,
Center( child: SizedBox( width: 200, height: 200, child: Stack( fit: StackFit.expand, children: [ const Center( child: Text( "70%", style: TextStyle( fontSize: 48, fontWeight: FontWeight.w900, color: Colors.purple, ), ), ), CustomPaint( painter: RingPainter( percentage: 70, width: 20, ), ), ], ), ), )
1条答案
按热度按时间ecfsfe2w1#
您可以使用
CustomPainter
来实现相同的目的,将其与
CustomPaint
小工具配合使用,如果你想在戒指里写文字,