Flutter动画显示隐藏插件animated_visibility的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter动画显示隐藏插件animated_visibility的使用

Animated Visibility

通过AnimatedVisibility小部件,可以使用预构建的效果来动画化组件的出现和消失。

示例1 示例2

Getting Started

添加依赖

在您的Flutter项目的pubspec.yaml中添加以下依赖:

dependencies:
  animated_visibility: <latest_version>

导入包

在您的库中添加以下导入语句:

import 'package:animated_visibility/animated_visibility.dart';

基本用法

下面是一个简单的例子,展示了如何使用AnimatedVisibility小部件。通过设置visible属性为true或false来控制子组件的显示与隐藏,并且可以通过enterexit属性来定义进入和退出动画效果。

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

1 回复

更多关于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();
  }
}

在这个示例中,我们做了以下几件事:

  1. 使用AnimatedVisibility组件包裹一个红色的Container
  2. 通过visible属性控制Container的显示和隐藏。
  3. 使用replacement属性指定当Container不可见时显示的占位符(这里是一个空的Container)。
  4. 使用AnimationController来管理动画的持续时间和行为,这里我们设置了一个自动反向的动画。
  5. 使用ElevatedButton来切换isVisible状态,从而触发显示和隐藏动画。

请注意,在实际应用中,通常不会在每个AnimatedVisibility组件中创建一个新的AnimationController。为了优化性能和资源使用,通常会复用AnimationController或者通过AnimatedVisibility的上下文获取现有的控制器。在上面的例子中,我们展示了如何手动管理控制器,但在更复杂的应用中,可能需要更精细的控制和复用机制。

回到顶部