flutter实践:比例对比线图实现

需求: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,
  });

  @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;
}
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();
    }
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤面不加鱼丸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值