flutter - 问如何在flutter中实现设计问题
问题描述
大家好,我想问一下是否有可能使用代码来实现这种设计?我真的被卡住了,这是我想要实现的设计
但真正的问题是我只能做到这一点
这是我的示例代码:
在我的主要:
return Scaffold(
backgroundColor: Color(0xff012a60),
body: Stack(children: <Widget>[
/*_AnimatedCircle(
outerController: outerController,
innerController: innerController,
),*/
_OuterCircle(circleColor: Colors.blueGrey[900].withOpacity(.8)),
Column(children: <Widget>[
const Spacer(flex: 50),
Expanded(flex: 30, child: Container(color: Colors.white)),
const Spacer(flex: 20),
]),
Row(children: <Widget>[
const Spacer(flex: 80),
Transform.scale(
scale: 2.5,
child: Container(
width: MediaQuery.of(context).size.width * 0.2,
decoration: const BoxDecoration(
color: Colors.red, shape: BoxShape.circle)),
),
]),
// _OuterCircle(circleColor: Colors.blueAccent.withOpacity(.25)),
Row(children: <Widget>[
const Spacer(flex: 80),
Column(children: [
Spacer(flex: 60),
Transform.scale(
scale: 2.5,
child: Container(
width: MediaQuery.of(context).size.width * 0.2,
height: MediaQuery.of(context).size.width * 0.05,
decoration: const BoxDecoration(color: Colors.green)),
),
Spacer(flex: 24),
]),
]),
]),
);
这是我的另一堂课
class _OuterCircle extends StatelessWidget {
const _OuterCircle({Key key, this.circleColor}) : super(key: key);
final Color circleColor;
@override
Widget build(BuildContext context) {
return Transform.scale(
scale: 2,
child: Container(
width: MediaQuery.of(context).size.width * 0.47,
decoration: BoxDecoration(shape: BoxShape.circle, color: circleColor),
));
}
}
请帮助我真的坚持如何在飞镖代码中实现这种设计
解决方案
我认为将几何问题从最大区域分解为小区域更容易。
实现这一点的关键是使用Clip
(ClipOval, ClipRect...)
- 上半部分可以用右圆夹左圆来画
- 下半部分可以通过使用右圆剪切内部矩形来绘制
- 缩放堆栈区域
- 画左大圆(区域1)
- 绘制中间白色矩形(区域 2)
- 画出内有矩形的右圆(区域 3)
- 绘制中间相交部分(区域 4)
使用的小部件:ClipOval
, FractionallySizedBox
, AspectRatio
,
左大圈
class BigCircle extends StatelessWidget {
const BigCircle({this.color,Key key}):super(key: key);
final Color color;
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1,
child: Container(
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
),
);
}
}
class CustomClipOval extends CustomClipper<Rect> {
@override
Rect getClip(Size size) {
final width = size.width * 0.42;
return Rect.fromLTRB(
size.width - width,
(size.height - width) * 0.5,
size.width,
(size.height + width) * 0.5,
);
}
@override
bool shouldReclip(covariant CustomClipper<Rect> oldClipper) {
return false;
}
}
最后是栈
return Scaffold(
backgroundColor: const Color(0xff004471),
body: Transform.scale(
scale: 1.19,
child: Stack(children: <Widget>[
// Area 1
const Align(
alignment: Alignment.centerLeft,
child: BigCircle(
color: Color(0xff022c66),
),
),
// Area 2
Align(
alignment: const Alignment(0, 0.4),
child: FractionallySizedBox(
heightFactor: 0.23,
child: Container(
color: Colors.white,
),
),
),
// Area 3
ClipOval(
clipper: CustomClipOval(),
child: Container(
alignment: const Alignment(0, 0.46),
color: Colors.white,
child: FractionallySizedBox(
heightFactor: 0.14,
child: Container(
color: const Color(0xff335f86),
),
),
),
),
// Area 4
ClipOval(
clipper: CustomClipOval(),
child: const Align(
alignment: Alignment.centerLeft,
child: BigCircle(color: Color(0xff647294),),
),
),
]),
),
);