代码之家  ›  专栏  ›  技术社区  ›  Kavin-K

如何在颤振中绘制自定义形状

  •  1
  • Kavin-K  · 技术社区  · 7 年前

    我只想画一个旋转的轮子。怎么画这样的圆? enter image description here

    2 回复  |  直到 7 年前
        1
  •  2
  •   Yann39    7 年前

    解决方案是实现自定义绘制( CustomPainter )然后使用 arcTo 方法绘制轮子的每个部分。

    然后可以使用 canvas.drawPath .

    最后在任何你想使用的地方使用它 CustomPaint 小装置:

    完整工作示例 :

    import 'dart:math';
    import 'package:flutter/material.dart';
    
    class Home extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _HomeState();
      }
    }
    
    class WheelPainter extends CustomPainter {
      Path getWheelPath(double wheelSize, double fromRadius, double toRadius) {
        return new Path()
          ..moveTo(wheelSize, wheelSize)
          ..arcTo(Rect.fromCircle(radius: wheelSize, center: Offset(wheelSize, wheelSize)), fromRadius, toRadius, false)
          ..close();
      }
    
      Paint getColoredPaint(Color color) {
        Paint paint = Paint();
        paint.color = color;
        return paint;
      }
    
      @override
      void paint(Canvas canvas, Size size) {
        double wheelSize = 100;
        double nbElem = 6;
        double radius = (2 * pi) / nbElem;
    
        canvas.drawPath(getWheelPath(wheelSize, 0, radius), getColoredPaint(Colors.red));
        canvas.drawPath(getWheelPath(wheelSize, radius, radius), getColoredPaint(Colors.purple));
        canvas.drawPath(getWheelPath(wheelSize, radius * 2, radius), getColoredPaint(Colors.blue));
        canvas.drawPath(getWheelPath(wheelSize, radius * 3, radius), getColoredPaint(Colors.green));
        canvas.drawPath(getWheelPath(wheelSize, radius * 4, radius), getColoredPaint(Colors.yellow));
        canvas.drawPath(getWheelPath(wheelSize, radius * 5, radius), getColoredPaint(Colors.orange));
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return oldDelegate != this;
      }
    }
    
    class _HomeState extends State<Home> {
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: AppBar(
            title: Text('Wheel test'),
            leading: new Icon(Icons.insert_emoticon),
          ),
          backgroundColor: Colors.white,
          body: CustomPaint(
            child: Container(
              height: 300.0,
            ),
            painter: WheelPainter(),
          ),
        );
        //]));
      }
    }
    

    结果:

    Colored wheel screenshot

    如果你想画饼图,最好用图表库。

        2
  •  1
  •   yrojas    7 年前

    这是另一个解决方案 CustomPainter 使用 drawArc 方法绘制轮子的每个部分。在这里,您还可以接收到您想要的颜色和分区数。

    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    class MyPainter extends CustomPainter {
      void _drawSpeenWheel(Canvas canvas, Paint paint,
      {Offset center,
      double radius,
      List<double> sources,
      List<Color> colors,
      double startRadian}) {
      var total = 0.0;
      for (var d in sources) {
        total += d;
      }
      List<double> radians = [];
      for (var data in sources) {
        radians.add(data * 2 * pi / total);
      }
      for (int i = 0; i < radians.length; i++) {
        paint.color = colors[i % colors.length];
        canvas.drawArc(Rect.fromCircle(center: center, radius: radius),
          startRadian, radians[i], true, paint);
        startRadian += radians[i];
      }
    }
    
    @override
    void paint(Canvas canvas, Size size) {
     Paint paint = Paint()
      ..style = PaintingStyle.fill;
     Offset center = new Offset(size.width / 2, size.height / 2);
     double radius = min(size.width / 2, size.height / 2);
    
     _drawSpeenWheel(
       canvas,
       paint,
       sources: [1, 1, 1, 1, 1, 1],
       colors: [
         Colors.red,
         Colors.purple,
         Colors.blue,
         Colors.green,
         Colors.yellow,
         Colors.orange
       ],
       center: center,
       radius: radius,
       startRadian: 0.1,
      );
     }
    
     @override
     bool shouldRepaint(CustomPainter oldDelegate) {
       return oldDelegate != this;
     }
    }
    

    然后在你需要的地方使用它。

    import 'package:flutter/material.dart';
    import 'package:speen_wheel/speen_wheel.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
       home: MyHomePage(title: 'SpeenWheel'),
      );
     }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
     @override
     _MyHomePageState createState() => _MyHomePageState();
     }
    
     class _MyHomePageState extends State<MyHomePage> {
     @override
     Widget build(BuildContext context) {
       return Scaffold(
       appBar: AppBar(
        title: Text(widget.title),
       ),
       body: SpeenWheel(),
      );
     }
    }
    

    工作实例

    enter image description here