Flutter动画调试插件animation_debugger的使用
Flutter动画调试插件 animation_debugger
的使用
animation_debugger
是一个强大的工具,可以帮助开发者在Flutter应用中调试动画。通过这个插件,你可以暂停、快进、倒放或反向播放动画。本文将详细介绍如何使用这个插件,并提供一个完整的示例Demo。
功能简介
Animation Debugger
允许你通过以下方式控制动画:
- 暂停
- 快进
- 倒放
- 反向播放
只需简单地将现有的 AnimationController
包装在一个调用中即可实现这些功能:
// ⬇︎ Your old controller ⬇︎
final controller = AnimationDebugger.of(context).watch(AnimationController());
使用步骤
第一步:在应用根部使用 builder
包装器
你需要在应用的根部(通常是 MaterialApp
或 CupertinoApp
)使用内置的 builder
包装器。
示例1:直接使用内置 builder
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: Colors.blueAccent,
),
title: 'Animation Debugger',
home: const MyHomePage(),
builder: AnimationDebugger.builder, // ⬅︎ Use built-in builder
);
}
}
示例2:如果你已经在使用其他 builder
,可以使用 builderWrapper
例如,这里我们使用了 bot_toast
库中的 builder
:
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: Colors.blueAccent,
),
title: 'Animation Debugger',
home: const MyHomePage(),
builder: AnimationDebugger.builderWrapper(BotToastInit()), // ⬅︎ Use built-in builder-factory
);
}
}
第二步:包装你的 AnimationController
为了让 Animation Debugger
能够识别并控制你的动画控制器,你需要将它们包裹在 watch
方法中:
final AnimationController controller = AnimationDebugger.of(context).watch(AnimationController(debugLabel: 'some name'));
// 或者
final AnimationController controller2 = AnimationDebugger.of(context).watch(AnimationController(), label: 'just name');
为了便于区分不同的控制器,建议为每个控制器设置一个唯一的 debugLabel
。
调试
安装并配置好 animation_debugger
后,你会看到一个浮动小部件出现在应用屏幕顶部。点击它会弹出一个列表,显示所有可管理的控制器。
注意:此插件仅在调试模式下生效,在发布模式下不会嵌入到应用中。
限制
当前版本仅支持具有明确时间范围的“有界”控制器。加速/延迟播放以及动态更改播放时间的功能尚未实现。
完整示例 Demo
下面是一个完整的示例代码,展示了如何在实际项目中使用 animation_debugger
:
import 'dart:async';
import 'dart:math';
import 'package:animation_debugger/animation_debugger.dart';
import 'package:flutter/material.dart';
const backgroundEndColor = Color.fromRGBO(1, 103, 213, 1);
const backgroundStartColor = Color.fromRGBO(43, 88, 153, 1);
const inkColor = Colors.white;
const borderWidth = 3.0;
const gap = 15.0;
const bottomGap = gap * 5;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: Colors.blueAccent,
),
title: 'Animation Debugger',
home: const MyHomePage(),
builder: AnimationDebugger.builder, // ⬅︎ Use built-in builder
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
Curve get curve => Curves.linear;
Duration get duration => const Duration(seconds: 120);
final List<String> spaceObjects = [
'sun',
'mercury',
'venus',
'earth',
'mars',
'jupiter',
'saturn',
'uranus',
'neptune',
'pluto',
];
final List<int> daysInTheYear = [25, 88, 225, 365, 687, 4380, 10950, 30660, 60225, 90520];
List<double> get distances => [1, 100, 170, 260, 380, 530, 700, 860, 1040, 1200];
final List<AnimationController> controllers = [];
void initSpaceObjects() {
for (int i = 0; i < spaceObjects.length; i++) {
final String objectName = spaceObjects[i];
final int daysInTheYear = this.daysInTheYear[i];
final AnimationController controller = AnimationDebugger.of(context).watch(
AnimationController(
vsync: this,
debugLabel: objectName,
duration: Duration(seconds: daysInTheYear),
),
);
controllers.add(controller);
unawaited(controller.forward());
}
}
Widget buildPaper() {
return Positioned(
left: gap,
top: gap,
right: gap,
bottom: bottomGap,
child: GridPaper(
color: Colors.white.withOpacity(0.5),
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: inkColor, width: borderWidth),
),
),
),
);
}
List<Widget> buildObjects() {
final List<Widget> result = [];
final Size size = MediaQuery.of(context).size;
final double width = size.width - gap * 2 - borderWidth * 2;
final double height = size.height - bottomGap - gap - borderWidth * 2;
for (int i = 0; i < spaceObjects.length; i++) {
final String name = spaceObjects[i];
final AnimationController controller = controllers[i];
final double distance = distances[i];
final double fixMover = i == 6 || i == 7 ? -20 : -10;
final Widget spaceObject = Image.asset('assets/$name.png', height: i == 0 ? 50 : 30);
result.add(
AnimatedBuilder(
animation: controller,
builder: (BuildContext context, Widget? child) {
final double value = controller.value;
final double rads = value * 360 / 2 / pi;
const double multiplier = 0.65;
final double x = cos(rads) * distance * multiplier;
final double y = sin(rads) * distance * multiplier;
if (i == 0) {
return Positioned(
left: width / 2,
bottom: height / 2 * 1.2,
child: Transform.translate(
offset: Offset(fixMover, -5),
child: Transform.rotate(angle: rads, child: child!),
),
);
}
return Positioned(
left: (width / 2) + x,
bottom: (height / 2 * 1.2) + y,
child: Transform.translate(
offset: Offset(fixMover, -5),
child: child!,
),
);
},
child: spaceObject,
),
);
}
return result;
}
[@override](/user/override)
void dispose() {
for (final AnimationController controller in controllers) {
controller.dispose();
}
super.dispose();
}
[@override](/user/override)
void initState() {
super.initState();
initSpaceObjects();
}
[@override](/user/override)
Widget build(BuildContext context) {
return DecoratedBox(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [backgroundStartColor, backgroundEndColor],
begin: Alignment.bottomLeft,
end: Alignment.topRight,
stops: [0, 1],
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Stack(
fit: StackFit.expand,
children: [
/// ? GRID
buildPaper(),
...buildObjects(),
],
),
),
);
}
}
更多关于Flutter动画调试插件animation_debugger的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动画调试插件animation_debugger的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,animation_debugger
是一个非常有用的 Flutter 插件,它可以帮助开发者在开发过程中调试和可视化动画。以下是如何在 Flutter 项目中使用 animation_debugger
的一个简单示例代码案例。
步骤 1: 添加依赖
首先,在你的 pubspec.yaml
文件中添加 animation_debugger
依赖:
dependencies:
flutter:
sdk: flutter
animation_debugger: ^x.y.z # 请替换为最新版本号
然后运行 flutter pub get
来获取依赖。
步骤 2: 导入插件
在你的 Dart 文件中导入 animation_debugger
:
import 'package:flutter/material.dart';
import 'package:animation_debugger/animation_debugger.dart';
步骤 3: 使用 AnimationController 和 AnimationBuilder
创建一个简单的动画并使用 AnimationDebugger
来包裹你的动画组件。以下是一个完整的示例:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Animation Debugger Example'),
),
body: AnimationDebugger(
// 启用调试模式
enabled: true,
child: AnimatedWidgetExample(),
),
),
);
}
}
class AnimatedWidgetExample extends StatefulWidget {
@override
_AnimatedWidgetExampleState createState() => _AnimatedWidgetExampleState();
}
class _AnimatedWidgetExampleState extends State<AnimatedWidgetExample> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_animation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedBuilder(
animation: _animation,
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
builder: (context, child) {
return Transform.scale(
scale: _animation.value,
child: child,
);
},
),
);
}
}
解释
- 添加依赖:在
pubspec.yaml
文件中添加animation_debugger
依赖。 - 导入插件:在你的 Dart 文件中导入
animation_debugger
。 - 使用 AnimationController:创建一个
AnimationController
并配置动画时长和反向重复。 - 使用 AnimationBuilder:使用
AnimatedBuilder
来构建动画组件。 - 包裹 AnimationDebugger:用
AnimationDebugger
包裹你的动画组件,并设置enabled: true
来启用调试模式。
调试
运行你的 Flutter 应用,你将看到动画在运行,并且 AnimationDebugger
会在动画运行时提供可视化调试信息。
注意:animation_debugger
插件的具体使用方法和界面可能会随着版本更新而变化,请参考官方文档以获取最新的使用指南。