flutter - 在 Flutter 中绘制圆形菜单
问题描述
我正在尝试绘制一个圆形菜单,如下图所示,但是我是 Flutter 的新手,我不知道从哪里开始这样的事情。
如图所示,我将只有 8 个和平而不是 12 个,它们都是链接,每个链接都指向应用程序的不同部分。
在中心灰色区域,我们将有短文本
解决方案
我希望它会给一些东西开始。
脚步:
- 通过类似Figma的方式绘制 svg
- 使用path_parsing包
Path
从svg path
- Create
ShapeDecoration
reClipPath
,我已经选择ClipPath
了,但是ShapeDecoration
你可以添加阴影。 - 用于或旋转
Matrix4
。我选择了 `Transform.rotate 两次,它更快,但使用Path.transform是更清洁的方法。Path
Transform.rotate
- 使用角度的正弦和余弦计算菜单每个花瓣的位置。
- 稍微调整一下。
快乐编码!享受!
ps 如果我们在没有特定数量的情况下进行解决方案可能会更好。
示例代码:
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(
backgroundColor: Colors.amber,
body: SafeArea(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatelessWidget {
final items = [
ButtonData(title: 'one', onTap: () => print('1')),
ButtonData(title: 'two', onTap: () => print('2')),
ButtonData(title: 'three', onTap: () => print('3')),
ButtonData(title: 'four', onTap: () => print('4')),
ButtonData(title: 'five', onTap: () => print('5')),
ButtonData(title: 'six', onTap: () => print('6')),
ButtonData(title: 'seven', onTap: () => print('7')),
ButtonData(title: 'eight', onTap: () => print('8')),
ButtonData(onTap: () => print('center')),
];
@override
Widget build(BuildContext context) {
return Container(
height: 300,
width: 300,
child: Stack(
children: items
.asMap()
.map((index, buttonData) {
if (index < 8) {
var degree = 360 / 8 * index;
var radian = degree * degrees2Radians;
return MapEntry(
index,
Align(
alignment: Alignment(
math.sin(radian),
math.cos(radian),
),
child: Transform.rotate(
angle: -radian,
child: MenuPetal(angle: -radian, buttonData: buttonData),
),
),
);
}
return MapEntry(
index,
_centerButton(buttonData),
);
})
.values
.toList(),
),
);
}
Widget _centerButton(ButtonData buttonData) {
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(25),
child: GestureDetector(
onTap: buttonData.onTap,
child: Container(
width: 50,
height: 50,
color: Colors.black38,
),
),
),
);
}
}
class ButtonData {
final String title;
final void Function() onTap;
ButtonData({this.title, this.onTap});
}
class MenuPetal extends StatelessWidget {
const MenuPetal({
Key key,
this.angle,
this.buttonData,
}) : super(key: key);
final double angle;
final ButtonData buttonData;
final double factor = 0.38;
@override
Widget build(BuildContext context) {
return FractionallySizedBox(
heightFactor: factor,
widthFactor: factor,
child: GestureDetector(
onTap: buttonData.onTap,
child: ClipPath(
clipper: MyCustomClipper(),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image:
NetworkImage('https://source.unsplash.com/featured/?white'),
),
),
child: Padding(
padding: EdgeInsets.only(top: 60),
child: Transform.rotate(
angle: -angle,
child: Text(buttonData.title),
),
),
),
),
),
);
}
}
class MyCustomClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
var x = size.width / 100 * 0.802;
var y = size.height / 100;
var path = Path()
..moveTo(39.4 * x, 6.1 * y)
..cubicTo(43.2 * x, -1.8 * y, 57.1 * x, -1.8 * y, 60.9 * x, 6.1 * y)
..lineTo(99.1 * x, 84.1 * y)
..cubicTo(102.1 * x, 90.2 * y, 99.1 * x, 93.9 * y, 92.0 * x, 95.6 * y)
..cubicTo(67.4 * x, 101.7 * y, 36.9 * x, 101.7 * y, 9.2 * x, 95.6 * y)
..cubicTo(1.2 * x, 93.8 * y, -1.3 * x, 88.7 * y, 1.2 * x, 84.1 * y)
..lineTo(39.4 * x, 6.1 * y);
return path.shift(Offset(12, 0));
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}
推荐阅读
- geojson - 使用folium可视化时丢失geojson的特征属性信息
- firebase - 嗨,我的实时数据库规则没有意义,我希望 int 只允许上升 1,不能下降,也不能上升超过 1
- python - Tensorflow 自定义对象检测器:model_main_tf2 没有开始训练
- three.js - 无法在 CRA 上使用 textureloader three.js 渲染 svg
- angular - 在执行我的 ngOnInit 所有功能后,我如何执行任何功能
- c - 释放结构成员指向的内存
- javascript - 如何仅启用提交功能,当SMTH在下拉列表中
- python - 从 AsyncIOMotorCursor python 获取数据
- jenkins - 如何通过詹金斯 .exe 文件到 msi
- maven - maven 在本地存储库中缓存工件多长时间?