Flutter动画滚动插件animation_scroller的使用
Flutter动画滚动插件animation_scroller的使用
环境
Flutter 2.10.4 Dart >=2.16.2 <3.0.0
示例

介绍
// "Value" Scrolls to the bottom part.
_scrollController.widgetBuild(context, "Value", _scrollController.duration);
完整代码示例
import 'package:animation_scroller/animation_scroller.dart';
import 'package:flutter/material.dart';
class AnimationScroller extends ScrollController {
/// Returns [value] plus 1.
int addOne(int value) => value + 1;
bool? initFlg;
bool? animationFlg;
int? durationValue;
double? scrollOffset;
double? keyboardHeight;
double? _animationValue;
double? _containerValue;
double? _maxScrollExtent;
/// Notify logic of scroll status.
scrollState(ScrollNotification scrollNotification, double maxScrollExtent, double containerValue) {
/// Check the status of scrollNotification.
if (scrollNotification is ScrollStartNotification) {
} else if (scrollNotification is ScrollUpdateNotification) {
} else if (scrollNotification is ScrollEndNotification) {
scrollOffset = position.maxScrollExtent;
bool aFlg = (animationFlg ?? false);
/// Judgment by scroll amount.
_maxScrollExtent = maxScrollExtent;
if (_maxScrollExtent == containerValue && aFlg) {
animationFlg = false;
}
}
}
/// Initialization of each value.
reset() {
initFlg = true;
durationValue = 0;
scrollOffset = 0.0;
keyboardHeight = 0.0;
_animationValue = 0.0;
_containerValue = 0.0;
_maxScrollExtent = 0.0;
jumpTo(0.0);
animationFlg = false;
}
/// Bind with a widget.
widgetBuild(BuildContext context, double containerValue, int duration) {
bool iFlg = (initFlg ?? false);
bool aFlg = (animationFlg ?? false);
double kValue = (keyboardHeight ?? 0.0);
double cValue = (_containerValue ?? 0.0);
double offsetValue = (scrollOffset ?? 0.0);
/// Scroll judgment.
if (aFlg) {
/// Substitute keyboard height.
kValue = kValue <= MediaQuery.of(context).viewInsets.bottom
? MediaQuery.of(context).viewInsets.bottom
: kValue;
/// Substitute scroll amount.
scrollOffset = (scrollOffset ?? 0.0) <= position.maxScrollExtent
? position.maxScrollExtent
: (scrollOffset ?? 0.0);
/// Scroll judgment
if (offsetValue > cValue && iFlg) {
animationFlg = false;
/// Scroll animation method
_animationLogic(duration);
} else if (!iFlg) {
/// Scroll animation method
_animationLogic(duration);
}
_containerValue = containerValue;
}
}
/// Speed set and flg check.
speedCheck(FocusNode focusNode, int value) {
/// Check focusNode state.
switch (focusNode.hasFocus) {
case true:
durationValue = value;
animationFlg = true;
break;
}
}
/// Scroll animation.
_animationLogic(int duration) {
Future(() {
double offsetValue = (scrollOffset ?? 0.0);
double cValue = (_containerValue ?? 0.0);
/// Judgment by scroll amount.
if (offsetValue > cValue) {
/// Substitute the amount of animation.
_animationValue = offsetValue - cValue;
double aValue = (_animationValue ?? 0.0);
animateTo(aValue,
duration: Duration(milliseconds: duration), curve: Curves.linear);
}
});
}
}
使用说明
在示例中,点击文本框会滚动到指定位置。
主要代码解析
初始化和重置
// 初始化各变量
reset() {
initFlg = true;
durationValue = 0;
scrollOffset = 0.0;
keyboardHeight = 0.0;
_animationValue = 0.0;
_containerValue = 0.0;
_maxScrollExtent = 0.0;
jumpTo(0.0); // 滚动到顶部
animationFlg = false;
}
绑定到控件
// 绑定到控件
widgetBuild(BuildContext context, double containerValue, int duration) {
bool iFlg = (initFlg ?? false);
bool aFlg = (animationFlg ?? false);
double kValue = (keyboardHeight ?? 0.0);
double cValue = (_containerValue ?? 0.0);
double offsetValue = (scrollOffset ?? 0.0);
// 滚动判断
if (aFlg) {
// 替换键盘高度
kValue = kValue <= MediaQuery.of(context).viewInsets.bottom
? MediaQuery.of(context).viewInsets.bottom
: kValue;
// 替换滚动量
scrollOffset = (scrollOffset ?? 0.0) <= position.maxScrollExtent
? position.maxScrollExtent
: (scrollOffset ?? 0.0);
// 滚动判断
if (offsetValue > cValue && iFlg) {
animationFlg = false;
// 滚动动画方法
_animationLogic(duration);
} else if (!iFlg) {
// 滚动动画方法
_animationLogic(duration);
}
_containerValue = containerValue;
}
}
设置速度并检查标志
// 设置速度并检查标志
speedCheck(FocusNode focusNode, int value) {
// 检查焦点状态
switch (focusNode.hasFocus) {
case true:
durationValue = value;
animationFlg = true;
break;
}
}
滚动动画逻辑
// 滚动动画逻辑
_animationLogic(int duration) {
Future(() {
double offsetValue = (scrollOffset ?? 0.0);
double cValue = (_containerValue ?? 0.0);
// 判断滚动量
if (offsetValue > cValue) {
// 替换动画量
_animationValue = offsetValue - cValue;
double aValue = (_animationValue ?? 0.0);
animateTo(aValue,
duration: Duration(milliseconds: duration), curve: Curves.linear);
}
});
}
更多关于Flutter动画滚动插件animation_scroller的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter动画滚动插件animation_scroller的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,animation_scroller
是一个用于在 Flutter 中实现复杂滚动动画的插件。它通过预定义的动画曲线和配置,可以帮助开发者轻松实现平滑且吸引人的滚动效果。以下是一个简单的代码示例,展示了如何使用 animation_scroller
插件来实现一个带有动画滚动的页面。
首先,确保你已经在 pubspec.yaml
文件中添加了 animation_scroller
依赖:
dependencies:
flutter:
sdk: flutter
animation_scroller: ^x.y.z # 请替换为最新版本号
然后,运行 flutter pub get
来获取依赖。
接下来是一个示例代码,展示了如何使用 animation_scroller
来实现滚动动画:
import 'package:flutter/material.dart';
import 'package:animation_scroller/animation_scroller.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animation Scroller Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ScrollerDemo(),
);
}
}
class ScrollerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Animation Scroller Demo'),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
// 使用 AnimationScrollerController 和 ScrollPositionListener 包装内容
AnimationScrollerController(
controller: ScrollController(),
duration: Duration(seconds: 2),
curve: Curves.easeInOutQuad,
child: ScrollPositionListener(
child: Column(
children: <Widget>[
// 第一个动画元素
AnimatedBuilder(
animation: AnimationScroller.of(context).position,
child: Container(
height: 200,
color: Colors.red,
child: Center(child: Text('Animated Box 1')),
),
builder: (context, child, position) {
final double opacity = position.pixels / 300; // 假设滚动300像素时完全显示
return Opacity(
opacity: opacity.clamp(0.0, 1.0),
child: child,
);
},
),
// 添加一些填充内容,以便滚动
SizedBox(height: 400),
// 第二个动画元素
AnimatedBuilder(
animation: AnimationScroller.of(context).position,
child: Container(
height: 200,
color: Colors.green,
child: Center(child: Text('Animated Box 2')),
),
builder: (context, child, position) {
final double translateY = -50 * (1 - (position.pixels / 600).clamp(0.0, 1.0)); // 假设滚动600像素时完成上升动画
return Transform.translate(
offset: Offset(0, translateY),
child: child,
);
},
),
// 添加更多填充内容,以便滚动
SizedBox(height: 800),
],
),
),
),
],
),
),
);
}
}
在这个示例中:
- 我们创建了一个
SingleChildScrollView
,其中包含多个动画元素。 - 使用
AnimationScrollerController
和ScrollPositionListener
包装这些动画元素,以便可以监听滚动位置并应用动画。 - 对于每个动画元素,我们使用
AnimatedBuilder
来根据滚动位置动态调整其属性(如透明度和位置)。
请注意,上述代码中的动画参数(如滚动距离和动画曲线)可以根据实际需求进行调整。这个示例主要展示了如何使用 animation_scroller
插件的基本结构和概念。