Rishabh
Rishabh

Reputation: 2548

Flutter Circle Design

enter image description here

I want to make this kind of design with these white circles as a raised button.

Upvotes: 110

Views: 277153

Answers (7)

Sana Ebadi
Sana Ebadi

Reputation: 7220

You can use decoration like this :

Container(
  width: 60,
  height: 60,
  child: Icon(CustomIcons.option, size: 20),
  decoration: BoxDecoration(
    shape: BoxShape.circle,
    color: Color(0xFFe0f2f1),
  ),
)

Now you have circle shape and Icon on it.

enter image description here

Upvotes: 120

Dafi
Dafi

Reputation: 236

you can use Container and BoxDecoration:

Container(
   height: 200.0,
   width: 200.0,
   decoration: BoxDecoration(
     shape: BoxShape.circle,
     borderRadius: BorderRadius.circular(4.0),
     color: Colors.yellow,
   ),
   child: const SizedBox.shrink(),
)

Upvotes: 0

Pratik Lakhani
Pratik Lakhani

Reputation: 343

Try This!

Output

Code:

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

void main() async {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CircleDemo(),
    );
  }
}

class CircleDemo extends StatefulWidget {
  const CircleDemo({super.key});

  @override
  _CircleDemoState createState() => _CircleDemoState();
}

class _CircleDemoState extends State<CircleDemo> {
  final List<int> circlesCount = [
    12,
    6,
  ];
  final double mainRadius = 100.0;
  final double inRadius = 18.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SizedBox(
          width: 300.0,
          height: 300.0,
          child: Stack(
            children: <Widget>[
              Center(
                child: Container(
                  width: mainRadius * 2,
                  height: mainRadius * 2,
                  decoration: const BoxDecoration(
                    shape: BoxShape.circle,
                    color: Colors.black,
                  ),
                  child: Center(
                      child: CircleAvatar(
                    backgroundColor: Colors.orange,
                    radius: inRadius,
                  )),
                ),
              ),
              for (int i = 0; i < circlesCount.length; i++)
                ...List.generate(
                  circlesCount[i],
                  (index) {
                    double angle =
                        ((index + 1) * (math.pi * 2)) / circlesCount[i];
                    double radius = (mainRadius / (i + 1)) * 0.8;
                    double x = radius * math.cos(angle) + mainRadius;
                    double y = radius * math.sin(angle) + mainRadius;
                    return Positioned(
                      left: x + (32),
                      top: y + (32),
                      child: CircleAvatar(
                        backgroundColor: Colors.orange,
                        radius: inRadius,
                      ),
                    );
                  },
                ),
            ],
          ),
        ),
      ),
    );
  }
}

Upvotes: 2

Kairat
Kairat

Reputation: 788

May be not the most suitable but very concise solution to create a filled circle:

CircleAvatar(backgroundColor: _getColor())

Upvotes: 0

Andrey Gordeev
Andrey Gordeev

Reputation: 32469

More efficient way

I recommend drawing a circle with CustomPainter. It's very easy and way more efficient than creating a bunch of widgets/masks:

Flutter draw circle

/// Draws a circle if placed into a square widget.
/// https://stackoverflow.com/a/61246388/1321917
class CirclePainter extends CustomPainter {
  final _paint = Paint()
    ..color = Colors.red
    ..strokeWidth = 2
    // Use [PaintingStyle.fill] if you want the circle to be filled.
    ..style = PaintingStyle.stroke;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawOval(
      Rect.fromLTWH(0, 0, size.width, size.height),
      _paint,
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

Usage:

  Widget _buildCircle(BuildContext context) {
    return CustomPaint(
      size: Size(20, 20),
      painter: CirclePainter(),
    );
  }

Upvotes: 38

Ajay
Ajay

Reputation: 16300

Try This!

demo

I have added 5 circles you can add more. And instead of RaisedButton use InkResponse.

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(home: new ExampleWidget()));
}

class ExampleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Widget bigCircle = new Container(
      width: 300.0,
      height: 300.0,
      decoration: new BoxDecoration(
        color: Colors.orange,
        shape: BoxShape.circle,
      ),
    );

    return new Material(
      color: Colors.black,
      child: new Center(
        child: new Stack(
          children: <Widget>[
            bigCircle,
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.favorite_border),
              top: 10.0,
              left: 130.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.timer),
              top: 120.0,
              left: 10.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.place),
              top: 120.0,
              right: 10.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.local_pizza),
              top: 240.0,
              left: 130.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.satellite),
              top: 120.0,
              left: 130.0,
            ),
          ],
        ),
      ),
    );
  }
}

class CircleButton extends StatelessWidget {
  final GestureTapCallback onTap;
  final IconData iconData;

  const CircleButton({Key key, this.onTap, this.iconData}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    double size = 50.0;

    return new InkResponse(
      onTap: onTap,
      child: new Container(
        width: size,
        height: size,
        decoration: new BoxDecoration(
          color: Colors.white,
          shape: BoxShape.circle,
        ),
        child: new Icon(
          iconData,
          color: Colors.black,
        ),
      ),
    );
  }
}

Upvotes: 157

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657476

I would use a https://docs.flutter.io/flutter/widgets/Stack-class.html to be able to freely position widgets.

To create circles

  new BoxDecoration(
    color: effectiveBackgroundColor,
    image: backgroundImage != null
      ? new DecorationImage(image: backgroundImage, fit: BoxFit.cover)
      : null,
    shape: BoxShape.circle,
  ),

and https://docs.flutter.io/flutter/widgets/Transform/Transform.rotate.html to position the white dots.

Upvotes: 30

Related Questions