Flutter页面切换动画插件liquid_swipe的使用

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

Flutter页面切换动画插件liquid_swipe的使用

目录

简介

Liquid Swipe 是一个用于Flutter应用程序的页面切换动画插件,它能够创建出类似液体流动般的页面切换效果。这个插件灵感来源于Cuberto’s liquid swipeIntroViews-Flutter,并且已经过优化和适配,可以轻松集成到您的Flutter项目中。

开始使用

要开始使用 liquid_swipe 插件,请按照以下步骤操作:

  1. 添加依赖:在项目的 pubspec.yaml 文件中添加 liquid_swipe 作为依赖项。

    dependencies:
      liquid_swipe: ^3.1.0
    
  2. 获取包:通过命令行运行 flutter packages get 来安装该插件。

    flutter packages get
    
  3. 导入库:在需要使用的Dart文件顶部引入 liquid_swipe 库。

    import 'package:liquid_swipe/liquid_swipe.dart';
    

使用方法

基本用法

LiquidSwipe 需要一组 Widget(如 Container)来展示页面内容。您可以将这些页面传递给 LiquidSwipe 组件,并自定义一些属性以实现不同的动画效果。

final pages = [
  Container(color: Colors.blue, child: Center(child: Text('Page 1'))),
  Container(color: Colors.green, child: Center(child: Text('Page 2'))),
  Container(color: Colors.red, child: Center(child: Text('Page 3'))),
];

@override
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      body: LiquidSwipe(pages: pages),
    ),
  );
}

高级配置

除了基本的页面列表外,您还可以配置更多选项来自定义动画行为,例如滑动图标、波浪类型等。

LiquidSwipe(
  pages: pages,
  positionSlideIcon: 0.8, // 滑动图标的垂直位置(0.0 到 1.0)
  slideIconWidget: Icon(Icons.arrow_back_ios), // 自定义滑动图标
  onPageChangeCallback: (int page) => print("Current Page: $page"), // 页面改变时回调
  waveType: WaveType.liquidReveal, // 波浪类型
  enableLoop: true, // 是否循环播放
  ignoreUserGestureWhileAnimating: true, // 动画过程中忽略用户手势
);

完整示例代码

下面是一个完整的示例代码,展示了如何使用 LiquidSwipe.builder 创建带指示器和按钮的页面切换效果:

import 'dart:math';

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

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

class ItemData {
  final Color color;
  final String image;
  final String text1;
  final String text2;
  final String text3;

  ItemData(this.color, this.image, this.text1, this.text2, this.text3);
}

class WithBuilder extends StatefulWidget {
  @override
  _WithBuilder createState() => _WithBuilder();
}

class _WithBuilder extends State<WithBuilder> {
  int page = 0;
  late LiquidController liquidController;
  late UpdateType updateType;

  List<ItemData> data = [
    ItemData(Colors.blue, "assets/1.png", "Hi", "It's Me", "Sahdeep"),
    ItemData(Colors.deepPurpleAccent, "assets/1.png", "Take a", "Look At", "Liquid Swipe"),
    ItemData(Colors.green, "assets/1.png", "Liked?", "Fork!", "Give Star!"),
    ItemData(Colors.yellow, "assets/1.png", "Can be", "Used for", "Onboarding design"),
    ItemData(Colors.pink, "assets/1.png", "Example", "of a page", "with Gesture"),
    ItemData(Colors.red, "assets/1.png", "Do", "try it", "Thank you"),
  ];

  @override
  void initState() {
    liquidController = LiquidController();
    super.initState();
  }

  Widget _buildDot(int index) {
    double selectedness = Curves.easeOut.transform(
      max(
        0.0,
        1.0 - ((page) - index).abs(),
      ),
    );
    double zoom = 1.0 + (2.0 - 1.0) * selectedness;
    return Container(
      width: 25.0,
      child: Center(
        child: Material(
          color: Colors.white,
          type: MaterialType.circle,
          child: Container(
            width: 8.0 * zoom,
            height: 8.0 * zoom,
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Stack(
          children: <Widget>[
            LiquidSwipe.builder(
              itemCount: data.length,
              itemBuilder: (context, index) {
                return Container(
                  width: double.infinity,
                  color: data[index].color,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Image.asset(
                        data[index].image,
                        height: 300,
                        fit: BoxFit.contain,
                      ),
                      Padding(
                        padding: EdgeInsets.all(index != 4 ? 24.0 : 0),
                      ),
                      index == 4
                          ? Padding(
                              padding: const EdgeInsets.symmetric(horizontal: 70.0),
                              child: ExampleSlider(),
                            )
                          : SizedBox.shrink(),
                      Column(
                        children: <Widget>[
                          Text(
                            data[index].text1,
                            style: TextStyle(fontSize: 30, fontWeight: FontWeight.w600),
                          ),
                          Text(
                            data[index].text2,
                            style: TextStyle(fontSize: 30, fontWeight: FontWeight.w600),
                          ),
                          Text(
                            data[index].text3,
                            style: TextStyle(fontSize: 30, fontWeight: FontWeight.w600),
                          ),
                        ],
                      ),
                    ],
                  ),
                );
              },
              positionSlideIcon: 0.8,
              slideIconWidget: Icon(Icons.arrow_back_ios),
              onPageChangeCallback: pageChangeCallback,
              waveType: WaveType.liquidReveal,
              liquidController: liquidController,
              fullTransitionValue: 880,
              enableSideReveal: true,
              preferDragFromRevealedArea: true,
              enableLoop: true,
              ignoreUserGestureWhileAnimating: true,
            ),
            Padding(
              padding: EdgeInsets.all(20),
              child: Column(
                children: <Widget>[
                  Expanded(child: SizedBox()),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: List<Widget>.generate(data.length, _buildDot),
                  ),
                ],
              ),
            ),
            Align(
              alignment: Alignment.bottomRight,
              child: Padding(
                padding: const EdgeInsets.all(25.0),
                child: TextButton(
                  onPressed: () {
                    liquidController.animateToPage(page: data.length - 1, duration: 700);
                  },
                  child: Text("Skip to End"),
                  style: TextButton.styleFrom(
                      backgroundColor: Colors.white.withOpacity(0.01),
                      foregroundColor: Colors.black),
                ),
              ),
            ),
            Align(
              alignment: Alignment.bottomLeft,
              child: Padding(
                padding: const EdgeInsets.all(25.0),
                child: TextButton(
                  onPressed: () {
                    liquidController.jumpToPage(
                        page: liquidController.currentPage + 1 > data.length - 1
                            ? 0
                            : liquidController.currentPage + 1);
                  },
                  child: Text("Next"),
                  style: TextButton.styleFrom(
                      backgroundColor: Colors.white.withOpacity(0.01),
                      foregroundColor: Colors.black),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }

  pageChangeCallback(int lpage) {
    setState(() {
      page = lpage;
    });
  }
}

class ExampleSlider extends StatefulWidget {
  const ExampleSlider({Key? key}) : super(key: key);

  @override
  State<ExampleSlider> createState() => _ExampleSliderState();
}

class _ExampleSliderState extends State<ExampleSlider> {
  double sliderVal = 0;

  @override
  Widget build(BuildContext context) {
    return Slider(
        value: sliderVal,
        activeColor: Colors.white,
        inactiveColor: Colors.red,
        onChanged: (val) {
          setState(() {
            sliderVal = val;
          });
        });
  }
}

此代码片段展示了如何使用 LiquidSwipe.builder 构建具有多个页面的滑动视图,并且每个页面都包含图像、文本和其他交互元素。此外,还包含了底部的分页指示器以及跳转到最后一页和下一页的功能按钮。希望这段代码能帮助您更好地理解和应用 liquid_swipe 插件。


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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用liquid_swipe插件来实现页面切换动画的示例代码。liquid_swipe插件允许你创建流畅的页面切换效果,类似于卡片翻转或液体流动动画。

首先,你需要在你的pubspec.yaml文件中添加liquid_swipe依赖:

dependencies:
  flutter:
    sdk: flutter
  liquid_swipe: ^2.0.0  # 请检查最新版本号并替换

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

接下来是一个完整的示例代码,展示如何使用liquid_swipe

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

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

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

class LiquidSwipePage extends StatelessWidget {
  final List<Map<String, String>> pages = [
    {'title': 'Page 1', 'content': 'This is the content of page 1'},
    {'title': 'Page 2', 'content': 'This is the content of page 2'},
    {'title': 'Page 3', 'content': 'This is the content of page 3'},
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Liquid Swipe Demo'),
      ),
      body: LiquidSwipe(
        pages: pages.map((page) {
          return Container(
            color: Colors.grey[200],
            alignment: Alignment.center,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  page['title']!,
                  style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                ),
                SizedBox(height: 20),
                Text(
                  page['content']!,
                  style: TextStyle(fontSize: 18),
                ),
              ],
            ),
          );
        }).toList(),
        waveType: WaveType.liquid, // You can use WaveType.none, WaveType.liquid, or WaveType.ripple
        enableLoop: true, // Enable infinite loop
        fullTransitionValue: 200, // Controls the wave's height
        borderRadius: BorderRadius.circular(25), // Optional: Apply border radius to the pages
        onPageChanged: (index) {
          print('Page changed to index: $index');
        },
      ),
    );
  }
}

代码解释:

  1. 依赖安装

    • pubspec.yaml文件中添加liquid_swipe依赖。
  2. 主应用

    • MyApp是一个简单的MaterialApp,设置了应用的主题和主页。
  3. 页面内容

    • LiquidSwipePage是一个包含页面内容的无状态小部件。
    • pages列表包含每个页面的数据,每个页面由一个标题和内容组成。
  4. LiquidSwipe

    • pages参数接受一个页面小部件列表。
    • waveType参数定义了波浪类型,可以是WaveType.liquidWaveType.rippleWaveType.none
    • enableLoop参数启用无限循环。
    • fullTransitionValue参数控制波浪的高度。
    • borderRadius参数为页面小部件应用圆角(可选)。
    • onPageChanged回调在页面更改时被调用,可以用来处理页面更改事件。

运行这段代码,你将看到一个包含三个页面的应用,页面之间通过液体流动动画进行切换。你可以根据需要调整动画效果和页面内容。

回到顶部