需求:flutter实现一个左右对比线图,带有动画效果
效果图:

Dart
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,
),
],
),
);
}
Dart
class TdxMarketHistogramPainter extends CustomPainter {
//涨所占比例
final percent;
TdxMarketHistogramPainter({
required this.percent,
});
@override
void 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);
}
@override
bool shouldRepaint(TdxMarketHistogramPainter oldDelegate) => true;
@override
bool shouldRebuildSemantics(TdxMarketHistogramPainter oldDelegate) => true;
}
Dart
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();
}
}