Flutter滚动动画插件scroll_animator的使用
Flutter滚动动画插件 scroll_animator
的使用
scroll_animator
是一个提供平滑、动画滚动效果的 Flutter 插件,适用于鼠标滚轮、触控板、键盘以及编程方式的滚动操作。它包含了一些常用的滚动动画可以直接使用,并且也提供了灵活性来实现自定义的滚动动画。
功能演示
以下是一个示例应用程序,展示了该插件提供的功能:
示例代码
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:scroll_animator/scroll_animator.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) => MaterialApp(
// 自定义快捷键
shortcuts: {
...WidgetsApp.defaultShortcuts,
const SingleActivator(LogicalKeyboardKey.keyW): const ScrollIntent(direction: AxisDirection.up),
const SingleActivator(LogicalKeyboardKey.keyS): const ScrollIntent(direction: AxisDirection.down),
const SingleActivator(LogicalKeyboardKey.keyA): const ScrollIntent(direction: AxisDirection.left),
const SingleActivator(LogicalKeyboardKey.keyD): const ScrollIntent(direction: AxisDirection.right),
},
// 使用 AnimatedScrollAction 替换默认的 ScrollAction
actions: {
...WidgetsApp.defaultActions,
ScrollIntent: AnimatedScrollAction(),
},
home: AnimatedPrimaryScrollController(
animationFactory: const ChromiumEaseInOut(),
child: Builder(
builder: (context) => Scaffold(
appBar: AppBar(title: const Text('Scroll Animator Example')),
// 浮动按钮用于随机滚动到指定位置
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.question_mark),
onPressed: () {
final scrollController = PrimaryScrollController.of(context);
final offset = lerpDouble(
scrollController.position.minScrollExtent,
scrollController.position.maxScrollExtent,
Random().nextDouble(),
);
if (scrollController is AnimatedScrollController) {
scrollController.animateTo(offset ?? 0.0);
} else {
scrollController.animateTo(
offset ?? 0.0,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
}
},
),
// 包含 ListView 的 Focus 组件
body: Focus(
autofocus: true,
child: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) => ListTile(
title: Text('Item $index'),
),
),
),
),
),
),
);
}
滚动动画
该插件提供了两种内置的 ScrollAnimation
实现,直接从 Chromium 移植过来,并带有单元测试,确保它们在行为上与基于 Chromium 的浏览器完全相同。
ChromiumEaseInOut
这是大多数基于 Chromium 的浏览器的默认滚动动画,在启用 #smooth-scrolling
标志并禁用 #windows-scrolling-personality
标志时生效。
ChromiumImpulse
这是 Microsoft Edge 的默认滚动动画,也可以通过启用 #smooth-scrolling
和 #windows-scrolling-personality
标志在其他基于 Chromium 的浏览器中启用。
指针精度
触控板通常提供精确且频繁的滚动增量,但这并不意味着不需要平滑滚动。有些触控板会产生较大且不频繁的增量,类似于鼠标滚轮。因此,该插件处理所有滚动输入时不假设指针类型。
完整示例 Demo
下面是一个更完整的示例,展示了如何使用 scroll_animator
插件来创建一个具有平滑滚动效果的应用程序:
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:scroll_animator/scroll_animator.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Scroll Animator Example')),
body: _ScrollAnimatorExample(),
),
);
}
class _ScrollAnimatorExample extends StatefulWidget {
[@override](/user/override)
_ScrollAnimatorExampleState createState() => _ScrollAnimatorExampleState();
}
class _ScrollAnimatorExampleState extends State<_ScrollAnimatorExample> {
late final DateTime _startDateTime;
late final ScrollController _scrollController;
[@override](/user/override)
void initState() {
super.initState();
_startDateTime = DateTime.now();
_scrollController = AnimatedScrollController(animationFactory: const ChromiumEaseInOut());
}
void _receivedPointerSignal(PointerSignalEvent event) {
if (!kDebugMode) return;
if (event is PointerScrollEvent) {
debugPrint('PointerScrollEvent(dx: ${event.scrollDelta.dx}, dy: ${event.scrollDelta.dy})');
} else if (event is PointerScrollInertiaCancelEvent) {
debugPrint('PointerScrollInertiaCancelEvent()');
}
}
bool _receivedScrollNotification(ScrollNotification notification) {
if (!kDebugMode) return false;
if (notification is ScrollStartNotification) {
debugPrint('ScrollStartNotification()');
} else if (notification is ScrollEndNotification) {
debugPrint('ScrollEndNotification()');
} else if (notification is ScrollUpdateNotification) {
debugPrint('ScrollUpdateNotification(delta: ${notification.scrollDelta})');
} else if (notification is UserScrollNotification) {
debugPrint('UserScrollNotification(direction: ${notification.direction})');
} else {
debugPrint(notification.toString());
}
return false;
}
[@override](/user/override)
void dispose() {
_scrollController.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) => Listener(
onPointerSignal: _receivedPointerSignal,
child: NotificationListener<ScrollNotification>(
onNotification: _receivedScrollNotification,
child: ListView.builder(
controller: _scrollController,
itemCount: 100,
itemBuilder: (context, index) => ListTile(
title: Text('Item $index'),
),
),
),
);
}
更多关于Flutter滚动动画插件scroll_animator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter滚动动画插件scroll_animator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于Flutter中的scroll_animator
插件的使用,下面是一个具体的代码案例,展示了如何实现滚动动画效果。scroll_animator
插件允许你在Flutter应用中轻松地为滚动视图添加动画效果。
首先,确保你已经在pubspec.yaml
文件中添加了scroll_animator
依赖:
dependencies:
flutter:
sdk: flutter
scroll_animator: ^x.y.z # 替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是一个完整的示例代码,展示如何使用scroll_animator
来实现滚动动画:
import 'package:flutter/material.dart';
import 'package:scroll_animator/scroll_animator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Scroll Animator Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
late ScrollController _scrollController;
late AnimationController _animationController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_animationController = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
}
@override
void dispose() {
_scrollController.dispose();
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scroll Animator Demo'),
),
body: ScrollAnimator(
scrollController: _scrollController,
animationController: _animationController,
animationBuilder: (context, scrollPosition, animation) {
return AnimatedBuilder(
animation: animation,
child: Container(
height: 200,
color: Colors.amber,
child: Center(child: Text('Animated Content')),
),
builder: (context, child) {
return Transform.translate(
offset: Offset(0, animation.value * 50), // 调整动画效果
child: child,
);
},
);
},
child: ListView.builder(
controller: _scrollController,
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
),
),
);
}
}
代码解释
-
依赖导入: 确保在
pubspec.yaml
中添加了scroll_animator
依赖,并运行flutter pub get
。 -
初始化: 在
_MyHomePageState
中,我们初始化了ScrollController
和AnimationController
。AnimationController
用于控制动画的时长和循环。 -
ScrollAnimator的使用:
scrollController
:绑定到ListView的滚动控制器。animationController
:绑定到动画控制器。animationBuilder
:一个函数,用于构建动画效果。在这个例子中,我们使用AnimatedBuilder
和Transform.translate
来创建一个简单的垂直平移动画。
-
ListView: 使用
ListView.builder
来生成一个包含多个ListTile
的列表。
当你滚动列表时,绑定的动画将会根据滚动位置触发,从而在指定的内容上应用动画效果。
请注意,scroll_animator
插件的具体API和使用方式可能会随着版本更新而变化,因此建议查阅最新的官方文档以获取最准确的信息。