Kavin-K
Kavin-K

Reputation: 2117

How to draw a custom shape in flutter

I just want to draw a spin wheel. How to draw a circle like this? enter image description here

Upvotes: 8

Views: 8161

Answers (2)

yrojas
yrojas

Reputation: 41

Here's another solution with CustomPainter using drawArc method to draw each part of the wheel. Here you could also receive the colors and the number of divisions you want to have.

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;
 }
}

And then use it where you need it.

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(),
  );
 }
}

Working example

enter image description here

Upvotes: 1

Yann39
Yann39

Reputation: 15699

A solution is to implement a custom painter (CustomPainter) then use the arcTo method to draw each part of the wheel.

You can then set the color using canvas.drawPath.

Finally use it wherever you want using a CustomPaint widget :

Full working example :

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(),
      ),
    );
    //]));
  }
}

Result :

Colored wheel screenshot

If you attemp to draw pie charts you better go with a Charting library.

Upvotes: 7

Related Questions