Def*_*ine 5 transform hittest gesturedetector flutter
我想创建一个旋转动画,其中包含一组按钮(排列成圆圈),这些按钮从单击的中心按钮旋转和延伸。
虽然动画和旋转工作良好,并且打开按钮和关闭按钮工作顺利并且尽管旋转但仍响应 onTap(),但外部按钮在“onTap”-GestureDetector 方面不起作用。
目标:我想让红色容器可点击(例如GestureDetector)。问题:红色容器对 onTap() 没有反应。
import "dart:developer" as dev;
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:sdg3/Widget/rotation_controller.dart';
import 'package:sdg3/Widget/rotation_menu_button.dart';
import 'package:vector_math/vector_math.dart' show radians, Vector3;
class RadialMenu extends StatefulWidget {
final Widget open;
final Widget? close;
final int startAngle;
final List<RotationMenuButton> rotationButtons;
final RotationController? rotationController;
const RadialMenu({
Key? key,
this.rotationController,
required this.open,
this.startAngle = 0,
this.close,
required this.rotationButtons,
}) : super(key: key);
@override
createState() => _RadialMenuState();
}
class _RadialMenuState extends State<RadialMenu>
with SingleTickerProviderStateMixin {
late AnimationController controller;
late double maxButtonRadius;
@override
void initState() {
super.initState();
//get "biggest" button
maxButtonRadius = widget.rotationButtons.map((e) => e.size).reduce(max);
controller = AnimationController(
duration: const Duration(milliseconds: 1500), vsync: this)
..addListener(() => setState(() {}));
translation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(parent: controller, curve: Curves.easeInOutCirc),
);
scale = Tween<double>(
begin: 1.5,
end: 0.0,
).animate(
CurvedAnimation(parent: controller, curve: Curves.fastOutSlowIn),
);
rotation = Tween<double>(
begin: 0.0,
end: 360.0,
).animate(
CurvedAnimation(
parent: controller,
curve: const Interval(
0.0,
0.7,
curve: Curves.easeInOutCirc,
),
),
);
}
@override
Widget build(BuildContext context) {
Widget open = widget.open;
Widget? close = widget.close;
var buttonsMap = widget.rotationButtons.asMap();
List<Widget> buttons = buttonsMap.entries.map((e) {
RotationMenuButton button = e.value;
double singleangle = 360.0 / buttonsMap.length;
double angle = (e.key * singleangle + widget.startAngle) % 360;
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
double menuwidth = (min(constraints.maxWidth, constraints.maxHeight) -
maxButtonRadius) /
2.0;
//minimizie space between cicrles
double dimensionsOfButton = 1 + button.size * (1 - scale.value / 1.5);
double overlapRadiusOfButton =
2.0 * sin(radians(singleangle / 2.0)) * menuwidth;
if (dimensionsOfButton > overlapRadiusOfButton) {
dimensionsOfButton = overlapRadiusOfButton - 5;
}
return Visibility(
visible: scale.value < 1.0,
child: Container(
color: Colors.blue,
child: Transform(
transform: Matrix4.identity()
..translate(
(translation.value * menuwidth) * cos(radians(angle)),
(translation.value * menuwidth) * sin(radians(angle))),
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: dimensionsOfButton,
maxWidth: dimensionsOfButton),
child: GestureDetector(
onTap: () => dev.log("I was pushed"),
child: Container(color: Colors.red)),
),
),
),
);
},
);
}).toList(growable: false);
return AnimatedBuilder(
animation: controller,
builder: (context, widget) {
return Transform.rotate(
angle: radians(rotation.value),
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
if (close != null)
Transform.scale(
scale: 1.5 - scale.value,
child: GestureDetector(
onTap: _close,
child: close,
),
),
Transform.scale(
scale: scale.value,
child: GestureDetector(
onTap: _open,
child: open,
),
),
buttons.first
],
),
);
},
);
}
late final Animation<double> rotation;
late final Animation<double> translation;
late final Animation<double> scale;
@override
void dispose() {
controller.dispose();
super.dispose();
}
_open() {
controller.forward();
}
_close() {
controller.reverse();
}
Run Code Online (Sandbox Code Playgroud)
问题是 dev.log(“我被推了”)。它永远不会出现(墨水池也不起作用,GestureDetector.behaviour 也不起作用)。
这是动画的输出。蓝色容器仅用于可视化,其中容器放置在转换之前,红色容器是转换后正确的“按钮”,它不响应 onTap():
当我删除翻译时:
..translate(
(translation.value * menuwidth) * cos(radians(angle)),
(translation.value * menuwidth) * sin(radians(angle))),
Run Code Online (Sandbox Code Playgroud)
它有效,但这不是所需的输出。
我的印象是命中测试翻译不正确。你有好主意吗?谢谢!
我使用了使用定位而不是翻译的解决方法。你\xc2\xb4ll需要一点数学来重新定位它,但它可以与GestureDetector onTap()一起使用(这里没有显示,但它在按钮小部件内部),包括翻译:
\n return Visibility(\n visible: scale.value < 1.0,\n child: Stack(\n children: [\n Positioned(\n left: constraints.maxWidth / 2 -\n maxButtonRadius / 2 +\n (translation.value * menuwidth) * cos(radians(angle)),\n top: constraints.maxHeight / 2 -\n maxButtonRadius / 2 +\n (translation.value * menuwidth) * sin(radians(angle)),\n child: SizedBox(\n height: dimensionsOfButton,\n width: dimensionsOfButton,\n child: button,\n ),\n ),\n ],\n ),\n );\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1513 次 |
| 最近记录: |