需求:flutter實現一個左右對比線圖,帶有動畫效果
效果圖:
Widget _buildTop() {return Container(height: themeData.heightXl,padding: EdgeInsets.symmetric(horizontal: themeData.hSpacingMd),child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,crossAxisAlignment: CrossAxisAlignment.center,children: [TdxText((module.sellSum > 0? (module.sellSum / (module.buySum + module.sellSum) * 100).toStringAsFixed(2): "--") +"%",textColor: themeData.colorTextDown,),SizedBox(width: themeData.hSpacingSm,),Expanded(child: ClipRRect(borderRadius: BorderRadius.circular(themeData.radiusMd),child: LayoutBuilder(builder: (context, constraints) {return AnimatedBuilder(animation: _animationController,builder: (context, child) {return CustomPaint(size: Size(constraints.maxWidth, 6),painter: TdxHqggWdpkHistogramPainter(percent: _progressAnimation.value),);},);},),),),SizedBox(width: themeData.hSpacingSm,),TdxText((module.buySum > 0? (module.buySum / (module.buySum + module.sellSum) * 100).toStringAsFixed(2): "--") +"%",textColor: themeData.colorTextUp,),],),);}
class TdxMarketHistogramPainter extends CustomPainter {//漲所占比例final percent;TdxMarketHistogramPainter({required this.percent,});@overridevoid paint(Canvas canvas, Size size) {//漲---進度條var paint1 = Paint()..style = PaintingStyle.fill..color = uiCommonConfig.colorTextUp;var path1 = Path()..moveTo(0, 0)..lineTo(max(size.width * percent, 0), 0)..lineTo(max(size.width * percent - 8, 0), size.height)..lineTo(0, size.height);//灰色區域var paint2 = Paint()..style = PaintingStyle.fill..color = uiCommonConfig.colorTextSecondary;var path2 = Path()..moveTo(max(size.width * percent + 4, 0), 0)..lineTo(max(size.width * percent + 10, 0), 0)..lineTo(size.width * percent + 2, size.height)..lineTo(max(size.width * percent - 4, 0), size.height);//跌---進度條var paint3 = Paint()..style = PaintingStyle.fill..color = uiCommonConfig.colorTextDown;var path3 = Path()..moveTo(size.width * percent + 14, 0)..lineTo(size.width, 0)..lineTo(size.width, size.height)..lineTo(size.width * percent + 6, size.height);//繪制canvas.drawPath(path1, paint1);canvas.drawPath(path2, paint2);canvas.drawPath(path3, paint3);}@overridebool shouldRepaint(TdxMarketHistogramPainter oldDelegate) => true;@overridebool shouldRebuildSemantics(TdxMarketHistogramPainter oldDelegate) => true;
}
late AnimationController _animationController; //動畫控制器
late Animation _progressAnimation; //進度條動畫
double oldRisePercnet = 0.5; //漲所占比例(舊)
double risePercnet = 0.5; //漲所占比例
void initAnimation() {//下面幾個值需要初始化int totalCount = module.buySum + module.sellSum; //買賣總量_animationController = AnimationController(duration: const Duration(milliseconds: 300), vsync: this);risePercnet = module.sellSum != 0 ? module.sellSum / totalCount : 0.5;_progressAnimation = Tween(begin: oldRisePercnet, end: risePercnet).animate(_animationController);//執行動畫_animationController.forward();oldRisePercnet = risePercnet;if (module.buySum > 0 && module.sellSum > 0) {module.updateDisplay();}}