Flutter故事视图展示插件story_view的使用

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

Flutter故事视图展示插件story_view的使用

插件简介

story_view 是一个用于在Flutter应用程序中创建类似WhatsApp和Instagram的故事视图的插件。它支持图片、GIF、视频,并且可以内联显示在ListView或Column中,就像Google News应用一样。此外,它还提供了手势控制(暂停、快退和快进)、每个故事项的标题和动画进度指示器等功能。

story_view

特性

  • 🎮 支持静态图片、GIF和视频(启用缓存)
  • 📍 手势控制:暂停、快退和快进
  • ⚜️ 每个故事项的标题
  • 🎈 动画进度指示器
  • 📱 全屏或内联显示

安装

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

  1. 在您的pubspec.yaml文件中添加依赖:

    dependencies:
      story_view: ^最新版本号
    
  2. 运行flutter pub get来安装依赖。

  3. 导入包:

    import 'package:story_view/story_view.dart';
    

使用方法

基础用法

通过StoryView类添加故事到屏幕或视图层次结构中。StoryView需要一个StoryItem列表作为参数,每个StoryItem描述了每个故事页面的内容、持续时间等信息。以下是几种常用的StoryItem创建方式:

  • StoryItem.text: 创建仅包含文本的故事页。
  • StoryItem.pageImage: 创建带有标题的图片故事页。
  • StoryItem.inlineImage: 创建适用于线性视图层次结构(如ListColumn)中的图片故事页。
  • StoryItem.pageVideo: 创建带有视频媒体的故事页。

示例代码

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

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

class MyApp extends StatelessWidget {
  @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
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Delicious Ghanaian Meals"),
      ),
      body: Container(
        margin: EdgeInsets.all(8),
        child: ListView(
          children: <Widget>[
            Container(
              height: 300,
              child: StoryView(
                controller: controller,
                storyItems: [
                  StoryItem.text(
                    title: "Hello world!\nHave a look at some great Ghanaian delicacies. I'm sorry if your mouth waters. \n\nTap!",
                    backgroundColor: Colors.orange,
                    roundedTop: true,
                  ),
                  StoryItem.inlineImage(
                    url: "https://image.ibb.co/cU4WGx/Omotuo-Groundnut-Soup-braperucci-com-1.jpg",
                    controller: controller,
                    caption: Text(
                      "Omotuo & Nkatekwan; You will love this meal if taken as supper.",
                      style: TextStyle(
                        color: Colors.white,
                        backgroundColor: Colors.black54,
                        fontSize: 17,
                      ),
                    ),
                  ),
                  StoryItem.inlineImage(
                    url: "https://media.giphy.com/media/5GoVLqeAOo6PK/giphy.gif",
                    controller: controller,
                    caption: Text(
                      "Hektas, sektas and skatad",
                      style: TextStyle(
                        color: Colors.white,
                        backgroundColor: Colors.black54,
                        fontSize: 17,
                      ),
                    ),
                  )
                ],
                onStoryShow: (storyItem, index) {
                  print("Showing a story");
                },
                onComplete: () {
                  print("Completed a cycle");
                },
                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("View more stories", style: TextStyle(fontSize: 16, color: Colors.white),),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MoreStories extends StatefulWidget {
  @override
  _MoreStoriesState createState() => _MoreStoriesState();
}

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

  @override
  void dispose() {
    storyController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("More"),
      ),
      body: StoryView(
        storyItems: [
          StoryItem.text(
            title: "I guess you'd love to see more of our food. That's great.",
            backgroundColor: Colors.blue,
          ),
          StoryItem.text(
            title: "Nice!\n\nTap to continue.",
            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: Text("Still sampling", style: TextStyle(fontSize: 15, color: Colors.white,), textAlign: TextAlign.center,),
            controller: storyController,
          ),
          StoryItem.pageImage(
            url: "https://media.giphy.com/media/5GoVLqeAOo6PK/giphy.gif",
            caption: Text("Working with gifs", style: TextStyle(fontSize: 15, color: Colors.white,), textAlign: TextAlign.center,),
            controller: storyController,
          ),
          StoryItem.pageImage(
            url: "https://media.giphy.com/media/XcA8krYsrEAYXKf4UQ/giphy.gif",
            caption: Text("Hello, from the other side", style: TextStyle(fontSize: 15, color: Colors.white,), textAlign: TextAlign.center,),
            controller: storyController,
          ),
          StoryItem.pageImage(
            url: "https://media.giphy.com/media/XcA8krYsrEAYXKf4UQ/giphy.gif",
            caption: Text("Hello, from the other side2", style: TextStyle(fontSize: 15, color: Colors.white,), textAlign: TextAlign.center,),
            controller: storyController,
          ),
        ],
        onStoryShow: (storyItem, index) {
          print("Showing a story");
        },
        onComplete: () {
          print("Completed a cycle");
        },
        progressPosition: ProgressPosition.top,
        repeat: false,
        controller: storyController,
      ),
    );
  }
}

以上代码展示了如何使用story_view插件创建一个简单的应用,其中包括两个页面:首页展示了一些美食的照片故事,点击“查看更多”按钮后会跳转到另一个页面展示更多内容。希望这对您有所帮助!如果您有任何问题或需要进一步的帮助,请随时提问。


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

1 回复

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


当然,以下是一个关于如何在Flutter中使用story_view插件来展示故事视图的代码示例。story_view插件通常用于创建类似于Instagram和Snapchat中的故事页面。

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

dependencies:
  flutter:
    sdk: flutter
  story_view: ^最新版本号  # 请替换为实际的最新版本号

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

接下来,在你的Flutter项目中创建一个新的Dart文件,例如story_screen.dart,并在其中编写以下代码:

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

class StoryScreen extends StatefulWidget {
  @override
  _StoryScreenState createState() => _StoryScreenState();
}

class _StoryScreenState extends State<StoryScreen> {
  final List<String> imageUrls = [
    'https://example.com/image1.jpg',
    'https://example.com/image2.jpg',
    'https://example.com/image3.jpg',
    // 添加更多图片URL
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: StoryView(
          imageUrls: imageUrls,
          onComplete: () {
            // 当所有故事播放完毕后执行的操作
            print("所有故事已播放完毕");
          },
          onPageChange: (int currentPage, int totalPages) {
            // 页面变化时的回调
            print("当前页面: $currentPage, 总页面数: $totalPages");
          },
          onTap: (int index) {
            // 点击某个页面时的回调
            print("点击了第 $index 页");
          },
          duration: const Duration(seconds: 3), // 每页显示时间
          aspectRatio: 16 / 9, // 宽高比
          startDelay: const Duration(seconds: 1), // 开始前的延迟
          progressIndicatorColor: Colors.white, // 进度指示器颜色
          dotColor: Colors.white, // 圆点颜色
          dotActiveColor: Colors.red, // 当前选中圆点颜色
          dotSize: 8.0, // 圆点大小
          dotSpacing: 12.0, // 圆点间距
          controller: StoryController(), // 可选的控制器
        ),
      ),
    );
  }
}

在上面的代码中,我们创建了一个StoryScreen小部件,它使用了StoryView来展示一系列图片。imageUrls列表包含了所有要展示的图片的URL。StoryView的构造函数接受多个参数,允许你自定义故事的外观和行为,例如:

  • imageUrls: 图片URL列表。
  • onComplete: 所有故事播放完毕后的回调。
  • onPageChange: 页面变化时的回调。
  • onTap: 点击某个页面时的回调。
  • duration: 每页显示的时间。
  • aspectRatio: 宽高比。
  • startDelay: 开始前的延迟。
  • progressIndicatorColor: 进度指示器颜色。
  • dotColor: 圆点颜色。
  • dotActiveColor: 当前选中圆点颜色。
  • dotSize: 圆点大小。
  • dotSpacing: 圆点间距。
  • controller: 可选的控制器,用于更精细的控制(例如暂停和继续播放)。

最后,在你的主应用文件中(例如main.dart),引入并使用StoryScreen

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StoryScreen(),
    );
  }
}

这样,运行你的Flutter应用时,就会看到一个使用story_view插件展示的故事视图。你可以根据自己的需求进一步自定义和扩展这个示例。

回到顶部