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

时间:2019-01-19 18:01:51

标签: dart flutter

我只想画一个旋转轮。如何画一个这样的圆? enter image description here

2 个答案:

答案 0 :(得分:2)

一种解决方案是实现自定义绘画工具(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

如果您想绘制饼图,最好使用图表库。

答案 1 :(得分:1)

这是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