Flutter动画展示插件story_view_lottie的使用

Flutter动画展示插件story_view_lottie的使用

story_view Pub

该插件用于在应用程序中展示故事,类似于WhatsApp和Instagram的故事功能。它还支持内联显示,就像Google新闻应用一样。此外,它还提供了暂停、快进和返回上一页的手势。

截图 截图 截图

👨‍🚀 示例项目:storyexample

🍟 视频演示:story_view demo

特性

  • 🕹 支持静态图像、GIF和视频(带缓存)
  • 📍 手势控制暂停、回放和快进
  • ⚜️ 每个故事项都有字幕
  • 🎈 每个故事项都有动画进度指示器
  • 有用的回调函数,可以执行元功能,包括垂直滑动手势。

安装

要使用此插件,在 pubspec.yaml 文件中添加 story_view 依赖项:

dependencies:
  story_view: ^版本号

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

使用

首先导入库:

import "package:story_view/story_view.dart";

查看 examples/example.dart 文件来了解如何使用此库。你可以将代码复制并粘贴到你的 main.dart 文件中运行,以便快速预览。

基本用法

使用 StoryView 将故事添加到屏幕或视图层次结构中。StoryView 需要一个 StoryItem 列表,每个 StoryItem 描述了每页故事要显示的内容、持续时间等。这使您可以自定义故事的每一页。

以下是创建不同类型故事项的快捷方式:

  • StoryItem.text 是创建只显示文本的故事页面的快捷方式。
  • StoryItem.pageImage 创建一个显示带有字幕的图片的故事项。
  • StoryItem.inlineImage 创建一个旨在显示在类似 ListColumn 的线性视图层次结构中的故事项。
  • StoryItem.pageVideo 创建一个带有视频媒体的故事页面。只需提供您的视频 URL 即可开始。

故事控制器、加载器和GIF支持

为了在图片加载时暂停故事,可以创建一个全局的 StoryController 实例,并在传递相同控制器实例的同时使用 StoryItem.pageImageStoryItem.inlineImage 快捷方式。

final controller = StoryController();

[@override](/user/override)
Widget build(context) {
  List<StoryItem> storyItems = [
    StoryItem.text(...),
    StoryItem.pageImage(...),
    StoryItem.pageImage(...),
    StoryItem.pageVideo(
      ...,
      controller: controller,
    )
  ]; // 你的故事列表

  return StoryView(
    storyItems,
    controller: controller, // 在这里也传递控制器
    repeat: true, // 是否应该永远滑动故事
    onStoryShow: (s) {notifyServer(s);},
    onComplete: () {},
    onVerticalSwipeComplete: (direction) {
      if (direction == Direction.down) {
        Navigator.pop(context);
      }
    } // 要禁用垂直滑动手势,请忽略此参数。适用于内联故事视图。
  );
}

现在,告诉你的用户一些故事吧。

示例代码

以下是一个完整的示例代码,展示了如何使用 story_view 插件来创建故事。

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.green,
        ),
        home: Home());
  }
}

class Home extends StatelessWidget {
  final StoryController controller = StoryController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("美味的加纳美食"),
      ),
      body: Container(
        margin: EdgeInsets.all(
          8,
        ),
        child: ListView(
          children: <Widget>[
            Container(
              height: 300,
              child: StoryView(
                controller: controller,
                storyItems: [
                  StoryItem.text(
                    title:
                        "你好世界!\n来看看一些很棒的加纳美食。如果你的口水流下来,我表示抱歉。\n\n点击!",
                    backgroundColor: Colors.orange,
                    roundedTop: true,
                  ),
                  StoryItem.inlineImage(
                    url:
                        "https://image.ibb.co/cU4WGx/Omotuo-Groundnut-Soup-braperucci-com-1.jpg",
                    caption: Text(
                      "Omotuo & Nkatekwan;如果你晚餐吃这道菜,你会喜欢的。",
                      style: TextStyle(
                        color: Colors.white,
                        backgroundColor: Colors.black54,
                        fontSize: 17,
                      ),
                    ),
                  ),
                  StoryItem.inlineImage(
                    url:
                        "https://media.giphy.com/media/5GoVLqeAOo6PK/giphy.gif",
                    caption: Text(
                      "Hektas, sektas 和 skatad",
                      style: TextStyle(
                        color: Colors.white,
                        backgroundColor: Colors.black54,
                        fontSize: 17,
                      ),
                    ),
                  )
                ],
                onStoryShow: (s) {
                  print("正在展示一个故事");
                },
                onComplete: () {
                  print("完成一个周期");
                },
                progressPosition: ProgressPosition.bottom,
                repeat: false,
                inline: true,
              ),
            ),
            Material(
              child: InkWell(
                onTap: () {
                  Navigator.of(context).push(
                      MaterialPageRoute(builder: (context) => MoreStories()));
                },
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.black54,
                      borderRadius:
                          BorderRadius.vertical(bottom: Radius.circular(8))),
                  padding: EdgeInsets.symmetric(vertical: 8),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Icon(
                        Icons.arrow_forward,
                        color: Colors.white,
                      ),
                      SizedBox(
                        width: 16,
                      ),
                      Text(
                        "查看更多故事",
                        style: TextStyle(fontSize: 16, color: Colors.white),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MoreStories extends StatefulWidget {
  [@override](/user/override)
  _MoreStoriesState createState() => _MoreStoriesState();
}

class _MoreStoriesState extends State<MoreStories> {
  final storyController = StoryController();

  [@override](/user/override)
  void dispose() {
    storyController.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("更多"),
      ),
      body: StoryView(
        storyItems: [
          StoryItem.text(
            title: "我想你会想看看更多的食物。那太好了。",
            backgroundColor: Colors.blue,
          ),
          StoryItem.text(
            title: "真好!\n\n点击继续。",
            backgroundColor: Colors.red,
            textStyle: TextStyle(
              fontFamily: 'Dancing',
              fontSize: 40,
            ),
          ),
          StoryItem.pageImage(
            url:
                "https://image.ibb.co/cU4WGx/Omotuo-Groundnut-Soup-braperucci-com-1.jpg",
            caption: "仍在试吃",
            controller: storyController,
          ),
          StoryItem.pageImage(
              url: "https://media.giphy.com/media/5GoVLqeAOo6PK/giphy.gif",
              caption: "处理GIF",
              controller: storyController),
          StoryItem.pageImage(
            url: "https://media.giphy.com/media/XcA8krYsrEAYXKf4UQ/giphy.gif",
            caption: "来自另一边的问候",
            controller: storyController,
          ),
          StoryItem.pageImage(
            url: "https://media.giphy.com/media/XcA8krYsrEAYXKf4UQ/giphy.gif",
            caption: "来自另一边的问候2",
            controller: storyController,
          ),
        ],
        onStoryShow: (s) {
          print("正在展示一个故事");
        },
        onComplete: () {
          print("完成一个周期");
        },
        progressPosition: ProgressPosition.top,
        repeat: false,
        controller: storyController,
      ),
    );
  }
}

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

1 回复

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


story_view_lottie 是一个用于在 Flutter 中展示动画的插件,它结合了 story_viewlottie 的功能,允许你在应用中展示类似于 Instagram 或 Snapchat 的故事视图,并且支持使用 Lottie 动画文件来增强视觉效果。

安装

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

dependencies:
  flutter:
    sdk: flutter
  story_view_lottie: ^latest_version

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

基本用法

以下是一个简单的示例,展示如何使用 story_view_lottie 插件来展示带有 Lottie 动画的故事视图。

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

class StoryViewExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Story View with Lottie'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => StoryViewLottiePage(),
              ),
            );
          },
          child: Text('Show Story'),
        ),
      ),
    );
  }
}

class StoryViewLottiePage extends StatelessWidget {
  final storyController = StoryController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StoryViewLottie(
        controller: storyController,
        storyItems: [
          StoryItemLottie(
            Lottie.asset('assets/animations/animation1.json'),
            duration: Duration(seconds: 5),
          ),
          StoryItemLottie(
            Lottie.asset('assets/animations/animation2.json'),
            duration: Duration(seconds: 5),
          ),
          StoryItemLottie(
            Lottie.asset('assets/animations/animation3.json'),
            duration: Duration(seconds: 5),
          ),
        ],
        onStoryShow: (storyItem, index) {
          print('Showing story $index');
        },
        onComplete: () {
          print('Story completed');
          Navigator.pop(context);
        },
        progressPosition: ProgressPosition.top,
        repeat: false,
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: StoryViewExample(),
  ));
}

参数说明

  • controller: 用于控制故事视图的 StoryController 实例。
  • storyItems: 一个包含 StoryItemLottie 的列表,每个 StoryItemLottie 包含一个 Lottie 动画和其持续时间。
  • onStoryShow: 当一个新的故事项开始展示时触发的回调。
  • onComplete: 当所有故事项展示完毕时触发的回调。
  • progressPosition: 进度条的位置,可以是 ProgressPosition.topProgressPosition.bottom
  • repeat: 是否重复播放故事。

自定义

你可以通过自定义 StoryItemLottie 来添加更多的交互和动画效果。例如,你可以在 Lottie 动画上叠加文本、图像或其他小部件。

StoryItemLottie(
  Lottie.asset('assets/animations/animation1.json'),
  duration: Duration(seconds: 5),
  onTap: () {
    print('Lottie animation tapped');
  },
  overlay: Text(
    'Custom Overlay Text',
    style: TextStyle(
      color: Colors.white,
      fontSize: 20,
    ),
  ),
),
回到顶部