What i am trying to achieve is: what i have achieved and stuck on is: i am using inkwell widget inside a container
Code:
Container(
alignment: Alignment.center,
child: InkWell(
child: new Container(
width: 120.0,
height: 120.0,
padding: const EdgeInsets.all(20.0),//I used some padding without fixed width and height
decoration: new BoxDecoration(
shape: BoxShape.circle,// You can use like this way or like the below line
// borderRadius: new BorderRadius.circular(30.0),
color: Colors.white,
),
child: new Text("", style: new TextStyle(color: Colors.black, fontSize: 30.0, fontWeight: FontWeight.bold)),
alignment: Alignment.center,
// You can add a Icon instead of text also, like below.
//child: new Icon(Icons.arrow_forward, size: 50.0, color: Colors.black38)),
),
please help.
maybe you can use Alignment(x, y)
and ClipPath
:
class Demo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Center(
child: Container(
color: Colors.grey,
width: 200,
height: 200,
child: Stack(
children: [
Align(
alignment: Alignment(-0.15, 0.3),
child: buildCircle(Colors.purpleAccent),
),
Align(
alignment: Alignment(0.2, 0.3),
child: buildCircle(Colors.blue),
),
Align(
alignment: Alignment(0.3, -0.1),
child: buildCircle(Colors.red),
),
Align(
alignment: Alignment(0.0, -0.3),
child: buildCircle(Colors.yellow),
),
Align(
alignment: Alignment(-0.3, -0.1),
child: ClipPath(
// Clip the green circle.
clipper: Clipper(),
child: buildCircle(Colors.green),
),
),
Align(
child: buildCircle(Colors.white, width: 30, height: 30),
),
],
),
),
),
);
}
Container buildCircle(
Color color, {
double width = 50,
double height = 50,
}) {
return Container(
alignment: Alignment.center,
width: width,
height: height,
child: InkWell(
child: new Container(
width: width,
height: height,
padding: const EdgeInsets.all(20.0),
//I used some padding without fixed width and height
decoration: new BoxDecoration(
shape: BoxShape.circle,
// You can use like this way or like the below line
// borderRadius: new BorderRadius.circular(30.0),
color: color,
),
child: new Text("",
style: new TextStyle(
color: Colors.black,
fontSize: 30.0,
fontWeight: FontWeight.bold)),
alignment: Alignment.center,
// You can add a Icon instead of text also, like below.
//child: new Icon(Icons.arrow_forward, size: 50.0, color: Colors.black38)),
),
),
);
}
}
class Clipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
return Path.combine(
PathOperation.difference,
Path()
..addOval(
Rect.fromCircle(
center: size.center(Offset(0, 0)),
radius: 25.0,
),
),
Path()
..addOval(
Rect.fromCircle(
center: size.center(Offset(10, 30)),
radius: 25.0,
),
),
);
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}
You can notice, that actually this is one element with different colors, it is going through the circle with angle of 360/5 degrees
Path.combine(
PathOperation.reverseDifference,
import 'dart:math' as math;
import 'package:flutter/material.dart';
const double degrees2Radians = math.pi / 180.0;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: SafeArea(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _currentSliderValue = 2;
List<Color> colors = [
Colors.blue,
Colors.red,
Colors.yellow,
Colors.green,
Colors.purple,
Colors.orange,
];
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: Container(
width: double.infinity,
child: CustomPaint(
painter: MyPainter(
colors: colors.take(_currentSliderValue).toList(),
),
),
),
),
Slider(
value: _currentSliderValue.toDouble(),
min: 2,
max: 6,
label: _currentSliderValue.toString(),
onChanged: (value) {
setState(() {
_currentSliderValue = value.round();
});
},
),
],
);
}
}
class MyPainter extends CustomPainter {
const MyPainter({
@required this.colors,
}) : super();
final List<Color> colors;
@override
void paint(Canvas canvas, Size size) {
var paths = <Color, Path>{};
colors.asMap().forEach((index, color) {
var degree = 360 / colors.length * (index + 0.5);
var radian = degree * degrees2Radians;
var path = _onePath(radian, size);
if (index > 0) {
path = Path.combine(
PathOperation.difference,
path,
paths[colors[index - 1]],
);
}
if (index == colors.length - 1) {
paths[colors[0]] = Path.combine(
PathOperation.reverseDifference,
path,
paths[colors[0]],
);
}
paths[color] = path;
});
for (final color in colors) {
var path = paths[color];
final fillPaint = Paint()
..color = color
..style = PaintingStyle.fill;
canvas.drawPath(path, fillPaint);
final strokePaint = Paint()
..color = Color(0xFFC4C4C4)
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.butt
..strokeWidth = 10;
canvas.drawPath(path, strokePaint);
}
}
Path _onePath(double radian, Size size) {
var circleSize = 150.0;
var center = size.center(Offset.zero);
var maxSize = math.min(size.height, size.width) / 4;
var sin = math.sin(radian);
var cos = math.cos(radian);
var rect = Rect.fromLTWH(
center.dx - circleSize / 2 + (sin * maxSize),
center.dy - circleSize / 2 + (cos * maxSize),
circleSize,
circleSize,
);
return Path()
..addRRect(
RRect.fromRectAndRadius(
rect,
Radius.circular(
rect.height / 2,
),
),
)
..close();
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
You can use FractionalTranslation
:
Center(
child: Container(
height: 400,
child: Stack(
children: <Widget>[
FractionalTranslation(
translation: Offset(-0.22, -0.1),
child: CircleContainer(color: Colors.green),
),
FractionalTranslation(
translation: Offset(-0.15, 0.2),
child: CircleContainer(color: Colors.purple),
),
FractionalTranslation(
translation: Offset(0.15, 0.2),
child: CircleContainer(color: Colors.blue),
),
FractionalTranslation(
translation: Offset(0.22, -0.1),
child: CircleContainer(color: Colors.red),
),
FractionalTranslation(
translation: Offset(0, -0.25),
child: CircleContainer(color: Colors.yellow),
),
CircleContainer(color: Colors.white, size: 130),
],
),
),
)
Widget CircleContainer({Color color = Colors.white, double size = 160}) {
return Container(
alignment: Alignment.center,
child: InkWell(
child: new Container(
width: size,
height: size,
padding: const EdgeInsets.all(
20.0), //I used some padding without fixed width and height
decoration: new BoxDecoration(
shape: BoxShape
.circle, // You can use like this way or like the below line
// borderRadius: new BorderRadius.circular(30.0),
color: color,
),
child: new Text("",
style: new TextStyle(
color: Colors.black,
fontSize: 30.0,
fontWeight: FontWeight.bold)),
alignment: Alignment.center,
// You can add a Icon instead of text also, like below.
//child: new Icon(Icons.arrow_forward, size: 50.0, color: Colors.black38)),
)));
}
Result:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.