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();
    }
  }
相关推荐
Aotman_几秒前
Vue el-table 字段自定义排序(进阶)
前端·javascript·vue.js·elementui·前端框架·ecmascript
Charonrise几秒前
完美解决Microsft Edge浏览器双击无法打开 双击无反应 无响应 不能用
前端·edge
华仔啊2 分钟前
这 5 个冷门 HTML 标签,让我直接删了100 行 JS 代码!
前端·html
西维6 分钟前
大屏、看板必备的丝滑技巧 — 数字滚动
前端·javascript·动效
前端工作日常10 分钟前
我学习到的AG-UI的功能:全面的交互支持
前端
LawrenceLan11 分钟前
Flutter 零基础入门(十三):late 关键字与延迟初始化
开发语言·前端·flutter·dart
深耕AI11 分钟前
【wordpress系列教程】03 网站页面的编辑
开发语言·前端
—Qeyser14 分钟前
Flutter Container 容器组件完全指南
flutter
前端达人18 分钟前
2026年React数据获取的第六层:从自己写缓存到用React Query——减少100行代码的秘诀
前端·javascript·react.js·缓存·前端框架