Reputation: 2548
I want to make this kind of design with these white circles as a raised button.
Upvotes: 110
Views: 277153
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.
Upvotes: 120
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
Reputation: 343
Try This!
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
Reputation: 788
May be not the most suitable but very concise solution to create a filled circle:
CircleAvatar(backgroundColor: _getColor())
Upvotes: 0
Reputation: 32469
I recommend drawing a circle with CustomPainter. It's very easy and way more efficient than creating a bunch of widgets/masks:
/// 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
Reputation: 16300
Try This!
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
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