flutter:纯手工绘制饼图

好累,不用插件真的是费神啊

本博主用flutter纯手工打造饼图,canvas绘制,好累,记得收藏学习哦,我的小粉丝们~

老规矩,看效果
在这里插入图片描述
上代码:

import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';


void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: piepage(),
    );
  }
}

class piepage extends StatefulWidget {
  @override
  _piepageState createState() => _piepageState();
}

Color mainColor = Color(0xFFCADCED);

class _piepageState extends State<piepage> with SingleTickerProviderStateMixin {
  AnimationController _animationController;

  Animation<double> _bgAnimation;

  Animation<double> _progressAnimation;

  Animation<double> _numberAnimation;

  @override
  void initState() {
    super.initState();

    _animationController = new AnimationController(
        duration: Duration(milliseconds: 1000), vsync: this);

    _bgAnimation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(0.0, 0.5),
    ));

    _progressAnimation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(0.4, 0.8),
    ));

    _numberAnimation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(0.7, 1.0),
    ));

    _animationController.addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          height: 260,
          width: MediaQuery.of(context).size.width,
          //背景
          color: mainColor,
          //封装方法
          child: buildRow(),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          _animationController.reset();
          _animationController.forward();
        },
      ),
    );
  }

  //定义数据模型
  List _list = [
    {"title": "生活费", "number": 200, "color": Colors.lightBlueAccent},
    {"title": "伙食费", "number": 200, "color": Colors.deepOrangeAccent},
    {"title": "交通费", "number": 400, "color": Colors.green},
    {"title": "网购", "number": 300, "color": Colors.red},
    {"title": "电话费", "number": 200, "color": Colors.orange}
  ];

  buildRow() {
    return Row(
      children: [
        Expanded(
          flex: 5,
          child: buildLeftColumn(), //左边
        ),
        //饼图区域
        Expanded(
            flex: 6,
            child: Stack(
              alignment: Alignment.center,
              children: [
                //第一层
                Container(
                  padding: EdgeInsets.all(22),
                  decoration: BoxDecoration(
                      color: mainColor,
                      shape: BoxShape.circle,
                      boxShadow: [
                        BoxShadow(
                          color: Colors.white,
                          spreadRadius: -8 * _bgAnimation.value,
                          offset: Offset(
                              -5 * _bgAnimation.value, -5 * _bgAnimation.value),
                          //阴影偏移量
                          blurRadius: 30 * _bgAnimation.value,
                        ),
                        BoxShadow(
                          color: Colors.blue[300].withOpacity(0.3),
                          spreadRadius: 2 * _bgAnimation.value,
                          offset: Offset(
                              5 * _bgAnimation.value, 5 * _bgAnimation.value),
                          //阴影偏移量
                          blurRadius: 20 * _bgAnimation.value,
                        )
                      ]),

                  //开始绘制
                  child: CustomPaint(
                    size: Size(200, 200),
                    painter:
                        CustomShapePainter(_list, _progressAnimation.value),
                  ),
                ),
              ],
            ))
      ],
    );
  }

//左边
  Column buildLeftColumn() {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: _list.map(
        (data) {
          return Container(
              padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
              child: Row(
                children: [
                  Container(
                    margin: EdgeInsets.only(right: 10),
                    width: 10,
                    height: 10,
                    decoration: BoxDecoration(
                      color: data['color'],
                      shape: BoxShape.circle,
                    ),
                  ),
                  Text(
                    data['title'],
                    style: TextStyle(fontSize: 16),
                  )
                ],
              ));
        },
      ).toList(),
    );
  }
}

class CustomShapePainter extends CustomPainter {
  List list;

  double progress;

  CustomShapePainter(this.list, this.progress);

  Paint _paint = new Paint()..isAntiAlias = true;

  @override
  void paint(Canvas canvas, Size size) {
    //中心
    Offset center = Offset(size.width / 2, size.height / 2);
    //半径
    double radius = min(size.width / 2, size.height / 2);
    //弧度
    double starRadian = -pi / 2;

    double total = 0.0;

    list.forEach((element) {
      total += element['number'];
    });

    for (var i = 0; i < list.length; i++) {
      var item = list[i];
      double flag = item['number'] / total;

      double sweepRadin = flag * 2 * pi * progress;

      _paint.color = item['color'];

      canvas.drawArc(Rect.fromCircle(center: center, radius: radius),
          starRadian, sweepRadin, true, _paint);

      starRadian += sweepRadin;
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}
相关推荐
<p> <br /> </p> <p> <br /> </p> <p> <br /> </p> <p> <b><span style="background-color:#FFE500;">【超实用课程内容】</span></b> </p> <p> <span>本课程根据实际开发中总结出来的一些学习思路,从零开始详细讲解</span><span>Flutter</span><span>的基础知识点。从简到难,从浅入深,逐步带领大家了解</span><span>Flutter</span><span>,熟悉</span><span>Flutter</span><span>的组成部分,并且带领大家学习如何使用</span><span>Flutter</span><span>实现</span><span>UI</span><span>功能编写。通过对本视频的学习,你将会掌握</span><span>Flutter</span><span>常用组件和常用布局构建复杂布局、</span><span>Flutter</span><span>路由导航实现多页面构建和交互、</span><span>Flutetr</span><span>手势处理和动画实现动态交互效果,以及如何使用音视频、片、文字、字体等资源。除此之外,你还可以收获每一章节遇到的重难点问题的解决方案。</span> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><span style="background-color:#FFE500;">【课程如何观看?】</span></b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端:<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/26150"></a><a href="https://edu.csdn.net/course/detail/26150"></a><a href="https://edu.csdn.net/course/detail/27286"></a><a href="https://edu.csdn.net/course/detail/26858"></a><a href="https://edu.csdn.net/course/detail/26227">https://edu.csdn.net/course/detail/26227</a> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端:CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课,课程永久有效观看时长,大家可以抓紧时间学习后一起讨论哦~ </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <strong><span style="background-color:#FFE500;">【学员专享增值服务】</span></strong> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b>源码开放</b> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化 </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 下载方式:电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/26150"></a><a href="https://edu.csdn.net/course/detail/27286"></a><a href="https://edu.csdn.net/course/detail/26858"></a><a href="https://edu.csdn.net/course/detail/26227">https://edu.csdn.net/course/detail/26227</a>,点击右下方课程资料、代码、课件等打包下载 </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页