Flutter动画切换插件fade_indexed_stack的使用

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

Flutter动画切换插件fade_indexed_stack的使用

fade_indexed_stack 是一个带有淡入淡出动画效果的 IndexedStack,并且支持懒加载功能。

启发来源

  • diegoveloper 提供了如何将 FadeTransition 应用于 IndexedStack 的 gist。
  • okaryo 提供了 lazy_load_indexed_stack 包。

使用方法

你可以像使用普通的 IndexedStack 一样使用 FadeIndexedStack。以下是一个简单的示例:

class MainPage extends StatefulWidget {
  const MainPage({super.key});

  [@override](/user/override)
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  int _currentIndex = 0;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: FadeIndexedStack(
        index: _currentIndex,
        children: [
          FirstPage(),
          SecondPage(),
          ThirdPage(),
        ],
      ),
      bottomNavigationBar: NavigationBar(
        destinations: [
          NavigationDestination(icon: Icon(Icons.home), label: "Home"),
          NavigationDestination(icon: Icon(Icons.person), label: "Profile"),
          NavigationDestination(icon: Icon(Icons.settings), label: "Settings"),
        ],
        selectedIndex: _currentIndex,
        onDestinationSelected: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}

在上面的示例中,FadeIndexedStack 会根据 _currentIndex 的变化来切换页面,并且带有淡入淡出的效果。底部导航栏的点击事件会更新 _currentIndex 的值,从而触发页面的切换。

更多细节

更多详细信息可以查看 示例文件

完整示例

以下是一个完整的示例,展示了如何使用 FadeIndexedStack 和底部导航栏来实现页面切换:

import 'package:fade_indexed_stack/fade_indexed_stack.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FadeIndexedStack 示例',
      theme: ThemeData(
        colorSchemeSeed: Colors.blue,
        useMaterial3: true,
      ),
      darkTheme: ThemeData(
        colorSchemeSeed: Colors.blue,
        useMaterial3: true,
        brightness: Brightness.dark,
      ),
      themeMode: ThemeMode.system,
      home: const NavigationView(),
    );
  }
}

class NavigationView extends StatefulWidget {
  const NavigationView({super.key});

  [@override](/user/override)
  State<NavigationView> createState() => _NavigationViewState();
}

class _NavigationViewState extends State<NavigationView> {
  int _currentIndex = 0;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: FadeIndexedStack(
        index: _currentIndex,
        lazy: true,
        duration: const Duration(milliseconds: 300),
        children: const [
          HomePage(),
          ProfilePage(),
          SettingsPage(),
        ],
      ),
      bottomNavigationBar: NavigationBar(
        destinations: const [
          NavigationDestination(
            icon: Icon(Icons.home),
            label: "Home",
          ),
          NavigationDestination(
            icon: Icon(Icons.person),
            label: "Profile",
          ),
          NavigationDestination(
            icon: Icon(Icons.settings),
            selectedIcon: Icon(Icons.settings),
            label: "Settings",
          ),
        ],
        selectedIndex: _currentIndex,
        onDestinationSelected: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("首页")),
      body: const Center(child: Text("首页")),
    );
  }
}

class ProfilePage extends StatelessWidget {
  const ProfilePage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("个人资料")),
      body: const Center(child: Text("个人资料页")),
    );
  }
}

class SettingsPage extends StatelessWidget {
  const SettingsPage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("设置")),
      body: const Center(child: Text("设置页")),
    );
  }
}

更多关于Flutter动画切换插件fade_indexed_stack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter动画切换插件fade_indexed_stack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,fade_indexed_stack 是一个在 Flutter 中用于创建动画切换效果的插件,非常适合在多个页面或视图之间平滑过渡。下面是一个使用 fade_indexed_stack 的代码示例,展示了如何实现简单的动画切换。

首先,确保你已经在 pubspec.yaml 文件中添加了 fade_indexed_stack 依赖:

dependencies:
  flutter:
    sdk: flutter
  fade_indexed_stack: ^x.y.z  # 请替换为最新版本号

然后,运行 flutter pub get 来安装依赖。

接下来是一个完整的 Flutter 应用示例,展示了如何使用 fade_indexed_stack

import 'package:flutter/material.dart';
import 'package:fade_indexed_stack/fade_indexed_stack.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fade Indexed Stack Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Fade Indexed Stack Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FadeIndexedStack(
              index: _currentIndex,
              alignment: Alignment.center,
              crossFadeAlignment: Alignment.center,
              duration: Duration(milliseconds: 500),
              children: <Widget>[
                Container(
                  color: Colors.red,
                  child: Center(child: Text('Page 1')),
                ),
                Container(
                  color: Colors.green,
                  child: Center(child: Text('Page 2')),
                ),
                Container(
                  color: Colors.blue,
                  child: Center(child: Text('Page 3')),
                ),
              ],
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _currentIndex = (_currentIndex + 1) % 3;
                    });
                  },
                  child: Text('Next'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

代码解释:

  1. 依赖导入:首先导入 fade_indexed_stack 插件。
  2. 应用结构:创建一个简单的 Flutter 应用,包含一个 MyApp 和一个 MyHomePage
  3. 状态管理:在 MyHomePage 中使用 StatefulWidgetSingleTickerProviderStateMixin 来管理状态。
  4. FadeIndexedStack 使用
    • index:当前显示的页面索引。
    • alignmentcrossFadeAlignment:控制子控件的对齐方式。
    • duration:动画持续时间。
    • children:包含要切换的页面(这里是三个不同颜色的容器)。
  5. 按钮切换:通过点击按钮来切换页面,使用 setState 方法更新 _currentIndex 以触发动画。

这个示例展示了如何使用 fade_indexed_stack 插件在 Flutter 应用中实现平滑的动画切换效果。你可以根据需要调整动画持续时间、对齐方式以及子控件的内容。

回到顶部