重现步骤
- 使用Flutter beta
- 粘贴代码
- 点击正方形,动画按预期工作
- 再次点击正方形,缩放不起作用,只有透明度起作用。
预期结果
缩放动画在后续的动画调用中应该起作用,而不仅仅是第一次。
实际结果
当缩放动画被多次调用时,它不起作用,而透明度动画可以。经过热重载后,只渲染缩放动画的最后一帧。有趣的是,如果我们用Transform.scale小部件替换Opacity小部件,一切都按预期工作(当Opacity包裹Transform.scale时,而不是Transform.scale包裹Opacity)。
代码示例
代码示例
class TestAnimation extends StatefulWidget {
const TestAnimation({super.key});
@override
State<TestAnimation> createState() => _TestAnimationState();
}
class _TestAnimationState extends State<TestAnimation>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
Animation<double> _scale = const AlwaysStoppedAnimation(0);
Animation<double> _opacity = const AlwaysStoppedAnimation(0);
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
_controller.addListener(() => setState(() {}));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
TickerFuture _animate() {
_scale = _controller.drive(
Tween<double>(
begin: 0,
end: 1.5,
),
);
_opacity = _controller.drive(
Tween<double>(
begin: 0,
end: 1,
),
);
return _controller.forward(from: 0);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: _animate,
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: Colors.green,
),
),
child: Transform.scale(
scale: _scale.value,
child: Opacity(
opacity: _opacity.value,
child: Container(
width: 50,
height: 50,
color: Colors.red,
),
),
),
),
);
}
}
截图或视频
截图/视频演示Screen.Recording.2024-07-14.at.4.27.32.PM.mov
日志
日志
[Paste your logs here]
Flutter Doctor输出
Doctor输出
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 3.23.0-0.1.pre, on macOS 14.5 23F79 darwin-arm64,
locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.90.2)
[✓] Connected device (5 available)
[✓] Network resources
• No issues found!
2条答案
按热度按时间ego6inou1#
可复现性:使用上述提供的代码示例
完整代码示例
flutter doctor -v
hmtdttj42#
似乎在
RenderOpacity
中存在一个涉及重绘边界逻辑的问题。当alpha值在零和非零之间转换时,
RenderOpacity.isRepaintBoundary
会发生变化。当这种情况发生时,会调用markNeedsCompositingBitsUpdate
,但出于某种原因,小部件仍然渲染为被裁剪到原始大小的样子。如果我将
_opacity
动画更改为从0.01
开始,这样alpha值永远不会为零,那么这个渲染就会正确。@jonahwilliams