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

需求: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();
    }
  }
相关推荐
JustHappy4 小时前
古法编程秘籍(七):互联网到底是什么?把两台电脑怎么说话搞懂就够了
前端·后端·网络协议
snow@li4 小时前
SEO-文章标题:写文章时候,分类+主标题+大纲+解释 作为标题 / 不点进去也知道全文覆盖什么 / 标题即架构
前端
kyriewen5 小时前
Git Commit 前自动修复代码风格?配置 Husky + lint-staged,从此 CR 只聊逻辑
前端·git·面试
小和尚同志5 小时前
AI 自动化测试探索(一):Playwright MCP
前端·人工智能·aigc
老马识途2.05 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
徐小夕6 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
运筹vivo@6 小时前
Python ContextVar 底层机制与内存模型拆解
前端·数据库·python
#麻辣小龙虾#8 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar8 小时前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github
weixin_471383038 小时前
Taro-02-页面路由
前端·taro