Flutter动画显示隐藏插件animated_visibility的使用
Flutter动画显示隐藏插件animated_visibility的使用
Animated Visibility
通过AnimatedVisibility小部件,可以使用预构建的效果来动画化组件的出现和消失。
Getting Started
添加依赖
在您的Flutter项目的pubspec.yaml
中添加以下依赖:
dependencies:
animated_visibility: <latest_version>
导入包
在您的库中添加以下导入语句:
import 'package:animated_visibility/animated_visibility.dart';
基本用法
下面是一个简单的例子,展示了如何使用AnimatedVisibility
小部件。通过设置visible
属性为true或false来控制子组件的显示与隐藏,并且可以通过enter
和exit
属性来定义进入和退出动画效果。
AnimatedVisibility(
visible: _isShow,
enter: fadeIn() + scaleIn(),
exit: fadeOut() + slideOutHorizontally(),
child: <content to show/hide>,
);
Demo
您可以参考官方示例应用,它演示了此库的实际使用是多么简单。
完整示例Demo
下面提供一个完整的示例demo,包括了不同类型的动画效果展示。
import 'package:animated_visibility/animated_visibility.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isShow = true;
void _toggleVisibility() {
setState(() {
_isShow = !_isShow;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF404349),
body: LayoutBuilder(
builder: (context, constraints) {
return GridView.count(
mainAxisSpacing: 2,
crossAxisSpacing: 2,
crossAxisCount: (constraints.maxWidth / 140).floor(),
childAspectRatio: 1,
padding: MediaQuery.of(context).padding +
const EdgeInsets.only(top: 16, bottom: 100, left: 4, right: 4),
children: [
// Various animation effects
_body("Fade", _content(enter: fadeIn(), exit: fadeOut())),
_body("Scale", _content(enter: scaleIn(), exit: scaleOut())),
_body(
"Fade+Scale",
_content(
enter: fadeIn() + scaleIn(),
exit: fadeOut() + scaleOut())),
_body("Slide", _content(enter: slideIn(), exit: slideOut())),
_body(
"Slide from top",
_content(
enter: slideInVertically(
initialOffsetY: -1,
curve: Curves.fastEaseInToSlowEaseOut),
exit: slideOutVertically(
targetOffsetY: -1,
curve: Curves.fastEaseInToSlowEaseOut))),
_body(
"Slide from bottom",
_content(
enter: slideInVertically(), exit: slideOutVertically())),
_body(
"Slide from start",
_content(
enter: slideInHorizontally(initialOffsetX: -1),
exit: slideOutHorizontally(targetOffsetX: -1))),
_body(
"Slide from end",
_content(
enter: slideInHorizontally(),
exit: slideOutHorizontally())),
_body(
"Expand Center Vertically",
_content(
enter: expandVertically(alignment: 0),
exit: shrinkVertically(alignment: 0))),
_body(
"Expand Center Horizontally",
_content(
enter: expandHorizontally(), exit: shrinkHorizontally())),
_body(
"Expand from top",
_content(
enter: expandVertically(alignment: -1),
exit: shrinkVertically(alignment: -1))),
_body(
"Expand from start",
_content(
enter: expandHorizontally(alignment: -1),
exit: shrinkHorizontally(alignment: -1))),
_body(
"Fade+Scale+Slide",
_content(
enter: fadeIn() + scaleIn() + slideInHorizontally(),
exit: fadeOut() + scaleOut() + slideOutHorizontally())),
_body(
"Expand+Fade",
_content(
enter: expandHorizontally(alignment: 1) +
fadeIn(initialAlpha: 0.5),
exit: shrinkHorizontally(alignment: 1) +
fadeOut(targetAlpha: 0.5))),
],
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: _toggleVisibility,
tooltip: 'Toggle Visibility',
child: Text(_isShow ? "Hide" : "Show"),
),
);
}
Widget _content({EnterTransition? enter, ExitTransition? exit}) =>
AnimatedVisibility(
visible: _isShow,
enter: enter ?? EnterTransitionNone.instance,
exit: exit ?? ExitTransitionNone.instance,
child: const Center(
child: CircleAvatar(
backgroundImage: AssetImage('assets/background.png'), // Please ensure you have the asset in your project.
radius: 60,
),
),
);
Widget _body(String label, Widget demo) => Container(
margin: const EdgeInsets.all(4),
color: Colors.black38,
child: Column(
children: [
Flexible(
child: Center(
child: ClipRRect(
child: demo,
),
)),
Container(
color: Colors.black12,
height: 38,
alignment: Alignment.center,
child: Text(label,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.white))),
],
),
);
}
注意:请确保您已经在项目中添加了相应的资源文件(如上面代码中的assets/background.png
),并且正确配置了pubspec.yaml
以包含这些资源。
更多关于Flutter动画显示隐藏插件animated_visibility的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动画显示隐藏插件animated_visibility的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用animated_visibility
插件来实现动画显示和隐藏组件的示例代码。
首先,确保你的pubspec.yaml
文件中已经添加了animated_visibility
依赖。如果还没有添加,请先添加:
dependencies:
flutter:
sdk: flutter
animated_visibility: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来是一个简单的示例,展示如何使用AnimatedVisibility
组件:
import 'package:flutter/material.dart';
import 'package:animated_visibility/animated_visibility.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animated Visibility Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
bool isVisible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Animated Visibility Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AnimatedVisibility(
visible: isVisible,
replacement: Container(), // 当不可见时显示的占位符
child: Container(
height: 100,
width: 100,
color: Colors.red,
child: Center(child: Text('I am animated!')),
),
animation: AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
)..repeat(reverse: true), // 自动反向动画
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
setState(() {
isVisible = !isVisible;
});
},
child: Text('Toggle Visibility'),
),
],
),
),
);
}
@override
void dispose() {
// 清理动画控制器
final AnimationController? controller = AnimatedVisibility.of(context)?.controller;
controller?.dispose();
super.dispose();
}
}
在这个示例中,我们做了以下几件事:
- 使用
AnimatedVisibility
组件包裹一个红色的Container
。 - 通过
visible
属性控制Container
的显示和隐藏。 - 使用
replacement
属性指定当Container
不可见时显示的占位符(这里是一个空的Container
)。 - 使用
AnimationController
来管理动画的持续时间和行为,这里我们设置了一个自动反向的动画。 - 使用
ElevatedButton
来切换isVisible
状态,从而触发显示和隐藏动画。
请注意,在实际应用中,通常不会在每个AnimatedVisibility
组件中创建一个新的AnimationController
。为了优化性能和资源使用,通常会复用AnimationController
或者通过AnimatedVisibility
的上下文获取现有的控制器。在上面的例子中,我们展示了如何手动管理控制器,但在更复杂的应用中,可能需要更精细的控制和复用机制。