Flutter动画堆栈插件animated_stack的使用
Flutter动画堆栈插件 animated_stack
的使用
animated_stack
是一个用于创建自定义可堆叠页面的Flutter插件,特别适用于侧边菜单按钮、分享按钮、消息发送、关于页面等场景。本文将详细介绍如何使用这个插件,并提供完整的示例代码。
功能概述
通过 animated_stack
,你可以轻松实现带有动画效果的堆叠页面。以下是一些主要功能:
- 自定义背景和前景部件
- 支持右侧面板(Column)和底部面板(Row)
- 可调整滑动动画的高度和宽度
- 设置FAB(Floating Action Button)图标及其颜色
- 自定义动画时长和曲线
快速开始
首先,你需要创建前景和背景部件。下面是一个简单的例子,展示了最低要求的配置:
import 'package:animated_stack/animated_stack.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animated Stack Demo',
theme: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: AnimatedStack(
backgroundColor: Colors.white,
fabBackgroundColor: Colors.black,
foregroundWidget: Container(), // 主页内容
columnWidget: Column(), // 右侧部件,建议使用Column
bottomWidget: Row(), // 底部部件,建议使用Row
),
);
}
}
完整功能列表
以下是你可以自定义的所有属性:
AnimatedStack(
backgroundColor: ..., // 背景容器颜色
foregroundWidget: ..., // 前景容器颜色
columnWidget: ..., // 右侧部件,建议使用Column
bottomWidget: ..., // 底部部件,建议使用Row
scaleHeight: 100, // 滑动动画高度,默认为60
scaleWidth: 100, // 滑动动画宽度,默认为60
buttonIcon: ..., // FAB图标 (IconData)
fabIconColor: ..., // FAB图标颜色
animateButton: false, // 是否启用按钮动画
fabBackgroundColor: ..., // FAB背景颜色
slideAnimationDuration: ..., // 滑动动画时长,默认为800毫秒
buttonAnimationDuration: ...,// 按钮动画时长,默认为240毫秒
openAnimationCurve: ..., // 打开动画曲线,默认为ElasticOutCurve(0.9)
closeAnimationCurve: ..., // 关闭动画曲线,默认为ElasticInCurve(0.9),
);
示例Demo
下面是一个更详细的示例,包含了前景、右侧和底部部件的具体实现:
import 'package:animated_stack/animated_stack.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animated Stack Demo',
theme: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: AnimatedStack(
backgroundColor: Color(0xff321B4A),
fabBackgroundColor: Color(0xffEB456F),
foregroundWidget: Container(
decoration: BoxDecoration(
color: Color(0xff56377C),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black26,
blurRadius: 30,
offset: Offset(4, 4),
),
],
borderRadius: BorderRadius.all(
Radius.circular(40),
),
),
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return _ItemPlaceholder();
},
),
),
columnWidget: Column(
children: <Widget>[
_IconTile(
width: 100,
height: 60,
iconData: Icons.share,
),
SizedBox(height: 20),
_IconTile(
width: 60,
height: 60,
iconData: Icons.image,
),
SizedBox(height: 20),
_IconTile(
width: 60,
height: 60,
iconData: Icons.camera_alt,
),
],
),
bottomWidget: Container(
decoration: BoxDecoration(
color: Color(0xff645478),
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
width: 260,
height: 50,
),
),
);
}
}
class _IconTile extends StatelessWidget {
final double width;
final double height;
final IconData iconData;
const _IconTile({
Key? key,
required this.width,
required this.height,
required this.iconData,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: width,
height: height,
decoration: BoxDecoration(
color: Color(0xff645478),
borderRadius: BorderRadius.all(
Radius.circular(15),
),
),
child: Icon(
iconData,
color: Color(0xffAEA6B6),
),
);
}
}
class _ItemPlaceholder extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 15),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipOval(
child: Container(
width: 60,
height: 60,
color: Color(0xff9783A9),
),
),
SizedBox(width: 15),
Expanded(
child: Container(
height: 120,
decoration: BoxDecoration(
color: Color(0xff6D528D),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(30),
topLeft: Radius.circular(30),
topRight: Radius.circular(20),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: _RowPlaceholder(color: 0xffA597B4),
width: MediaQuery.of(context).size.width * 2 / 5,
),
_RowPlaceholder(color: 0xff846CA1),
_RowPlaceholder(color: 0xff846CA1),
],
),
),
),
)
],
),
);
}
}
class _RowPlaceholder extends StatelessWidget {
final int color;
const _RowPlaceholder({Key? key, required this.color}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 15,
decoration: BoxDecoration(
color: Color(color),
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
);
}
}
许可证
该插件遵循 MIT License。
希望以上内容对你有所帮助!如果有任何问题,请随时提问。
更多关于Flutter动画堆栈插件animated_stack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动画堆栈插件animated_stack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于animated_stack
插件在Flutter中的使用,这里是一个具体的代码案例来展示如何创建一个动画堆栈。animated_stack
是一个第三方库,它扩展了Flutter内置的Stack
小部件,允许在堆栈中的子项之间进行平滑的过渡动画。
首先,确保在你的pubspec.yaml
文件中添加animated_stack
依赖:
dependencies:
flutter:
sdk: flutter
animated_stack: ^latest_version # 替换为最新版本号
然后运行flutter pub get
来获取依赖。
接下来是一个使用animated_stack
的示例代码:
import 'package:flutter/material.dart';
import 'package:animated_stack/animated_stack.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animated Stack Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Animated Stack Demo'),
),
body: AnimatedStackDemo(),
),
);
}
}
class AnimatedStackDemo extends StatefulWidget {
@override
_AnimatedStackDemoState createState() => _AnimatedStackDemoState();
}
class _AnimatedStackDemoState extends State<AnimatedStackDemo> 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, end: 1).animate(_controller);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedStack(
alignment: Alignment.center,
fit: StackFit.expand,
crossAxisAlignment: CrossAxisAlignment.center,
animation: _animation,
children: [
Positioned(
child: Container(
color: Colors.blue.withOpacity(0.5),
width: double.infinity,
height: double.infinity,
),
),
AnimatedStackItem(
animationValue: _animation.value,
child: Container(
color: Colors.red,
width: 100,
height: 100,
),
),
AnimatedStackItem(
animationValue: 1 - _animation.value,
child: Container(
color: Colors.green,
width: 100,
height: 100,
),
),
],
),
);
}
}
class AnimatedStackItem extends StatelessWidget {
final double animationValue;
final Widget child;
const AnimatedStackItem({Key? key, required this.animationValue, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Opacity(
opacity: animationValue,
child: child,
);
}
}
解释
- 依赖添加:在
pubspec.yaml
中添加animated_stack
依赖。 - 动画控制:使用
AnimationController
和Tween
来控制动画,这里动画持续2秒并反复进行。 - AnimatedStack:使用
AnimatedStack
来包裹子项。AnimatedStack
接受一个animation
参数,该参数控制堆栈中子项的动画。 - AnimatedStackItem:自定义一个
AnimatedStackItem
小部件,使用Opacity
根据animationValue
调整透明度,这里模拟堆栈中子项的淡入淡出效果。 - 布局:两个不同颜色的容器作为堆栈的子项,通过动画控制它们的透明度变化。
注意:由于animated_stack
库本身可能具有更多的功能和配置选项,建议查阅其官方文档以获取更多详细信息和高级用法。如果你发现Flutter官方仓库或社区有更推荐的动画堆栈解决方案,也可以考虑使用那些方法。