Flutter故事查看器插件story_viewer的使用

Flutter故事查看器插件story_viewer的使用

此插件为任何Flutter应用提供了常见的故事查看体验。

故事查看器示例

特性

  • 完整支持已知的手势;
    • 下一个故事、上一个故事
    • 长按隐藏UI层
  • 自定义文本、图标、颜色、填充等。
  • 简单实现故事和故事所有者用户的模型。
  • 垂直滑动下拉退出页面。
  • 像Instagram一样通过垂直滑动上拉回复故事(文字或表情)。
  • 动态视图内的显示比例。
  • 支持带有回调的监听器,用于故事播放控制器。
    • 播放、暂停、故事索引改变等。
  • 支持自定义的额外层,位于媒体层之下或之上。
  • 对于可能不适宜的媒体内容,提供模糊层。

默认且完全测试过的比例是9:16,并且全屏显示。

使用方法

这是story_viewer的基本用法:

StoryViewer(
    padding: EdgeInsets.all(8),
    backgroundColor: Colors.white,
    ratio: StoryRatio.r16_9,
    stories: [
        StoryItemModel(imageProvider: NetworkImage(imageURL)),
        StoryItemModel(imageProvider: MemoryImage(memoryImage)),
        StoryItemModel(imageProvider: AssetImage(assetName)),
    ],
    userModel: UserModel(
        username: username,
        profilePicture: NetworkImage(profileURL),
    ),
);

自定义控制器示例,包含事件监听器:

StoryViewerController controller = StoryViewerController();
controller.addListener(
    onPlayed: () {
        print("'onPlayed' 回调在故事查看器之外");
    },
    onPaused: () {
        print("'onPaused' 回调在故事查看器之外");
    },
);
return StoryViewer(
    viewerController: controller,
    .
    .
);

更多详细示例请查看example/lib/detailed_example.dart

依赖项

包名 类型 描述
extended_image 核心 缓存图像,滑动退出页面

示例代码

// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:example/detailed_example.dart';
import 'package:flutter/material.dart';
import 'package:story_viewer/models/story_item.dart';
import 'package:story_viewer/models/user.dart';
import 'package:story_viewer/viewer.dart';

var images1 = [
  'https://firebasestorage.googleapis.com/v0/b/app-monotony.appspot.com/o/assets%2FScreen%20Shot%202020-09-06%20at%2013.24.29.png?alt=media&token=30f1e802-e3f2-4cdb-b95c-b1f886bfeba2',
  'https://firebasestorage.googleapis.com/v0/b/app-monotony.appspot.com/o/assets%2FScreen%20Shot%202020-09-06%20at%2013.24.48.png?alt=media&token=69743845-dfcb-4245-83bf-3f543715e2bd',
  'https://firebasestorage.googleapis.com/v0/b/app-monotony.appspot.com/o/assets%2FScreen%20Shot%202020-09-06%20at%2013.27.04.png?alt=media&token=750c65a5-216b-4e6b-840d-8efe10042ed6'
];
var images2 = [
  'https://firebasestorage.googleapis.com/v0/b/app-monotony.appspot.com/o/assets%2Fmonotony-brand-02.png?alt=media&token=49d1d989-ac74-4d00-a816-e1680172e707',
  'https://lh3.googleusercontent.com/r87lupz1w9JaLb6_8UZtBWnR1bu4rjC6yWV69pqfSy2PZzB7lAwNjR8fyWyruShu_dk',
  'https://lh3.googleusercontent.com/vzstCu3rediu8YxljS-3oA7qNDVmet-Wl2VQpoWCOMN4zqirKdOAhNJZXU98Y6QMOiE=s180',
];

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

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

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(home: Home());
  }
}

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

class _HomeState extends State<Home> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('story_viewer'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          StoryViewer(
            padding: EdgeInsets.all(8),
            backgroundColor: Colors.white,
            ratio: StoryRatio.r16_9,
            stories: [
              StoryItemModel(imageProvider: NetworkImage(images1[0])),
              StoryItemModel(imageProvider: NetworkImage(images1[1])),
              StoryItemModel(imageProvider: NetworkImage(images1[2])),
            ],
            userModel: UserModel(
              username: 'flutter',
              profilePicture: NetworkImage(
                'https://cdn-images-1.medium.com/max/1200/1*5-aoK8IBmXve5whBQM90GA.png',
              ),
            ),
          ),
          MaterialButton(
              child: Text('探索更多!'),
              color: Colors.blue,
              onPressed: () {
                Navigator.of(context).push(MaterialPageRoute(
                    fullscreenDialog: true,
                    builder: (context) => DetailedHome()));
              }),
        ],
      ),
    );
  }
}

更多关于Flutter故事查看器插件story_viewer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter故事查看器插件story_viewer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


story_viewer 是一个用于在 Flutter 应用中实现类似 Instagram 或 Snapchat 故事查看功能的插件。它允许你以幻灯片的形式展示图片或视频,并提供用户交互功能,如滑动切换、暂停、播放等。

以下是如何在 Flutter 项目中使用 story_viewer 插件的步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 story_viewer 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  story_viewer: ^latest_version  # 使用最新版本

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

2. 导入插件

在你的 Dart 文件中导入 story_viewer 插件:

import 'package:story_viewer/story_viewer.dart';

3. 使用 StoryViewer

StoryViewer 是插件的主要组件,用于展示故事。你可以通过传递一个 StoryItem 列表来展示多个故事。

class StoryScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Story Viewer'),
      ),
      body: StoryViewer(
        storyItems: [
          StoryItem.image('https://via.placeholder.com/150'),
          StoryItem.image('https://via.placeholder.com/200'),
          StoryItem.video('https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4'),
        ],
        onComplete: () {
          // 当所有故事播放完毕时触发
          Navigator.pop(context);
        },
      ),
    );
  }
}

4. StoryItem 的使用

StoryItem 用于定义每个故事的内容。你可以使用 StoryItem.image 来展示图片,或者使用 StoryItem.video 来展示视频。

StoryItem.image(String url, {Duration? duration})
StoryItem.video(String url, {Duration? duration})
  • url: 图片或视频的 URL。
  • duration: 每个故事的持续时间,如果不指定,默认值为 5 秒。

5. 自定义选项

StoryViewer 提供了多种自定义选项,如控制故事播放速度、显示进度条、添加交互等。

StoryViewer(
  storyItems: [
    StoryItem.image('https://via.placeholder.com/150'),
    StoryItem.image('https://via.placeholder.com/200'),
  ],
  onComplete: () {
    Navigator.pop(context);
  },
  onStoryShow: (StoryItem storyItem) {
    print('Showing story: ${storyItem.url}');
  },
  progressPosition: ProgressPosition.top,
  repeat: false,
  inline: false,
);

6. 处理用户交互

你可以通过 onCompleteonStoryShow 等回调来处理用户交互。

  • onComplete: 当所有故事播放完毕时触发。
  • onStoryShow: 当每个故事开始播放时触发。

7. 运行应用

完成上述步骤后,你可以运行你的 Flutter 应用,查看 story_viewer 插件的效果。

flutter run

示例代码

以下是一个完整的示例代码:

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

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

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

class StoryScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Story Viewer'),
      ),
      body: StoryViewer(
        storyItems: [
          StoryItem.image('https://via.placeholder.com/150'),
          StoryItem.image('https://via.placeholder.com/200'),
          StoryItem.video('https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4'),
        ],
        onComplete: () {
          Navigator.pop(context);
        },
        onStoryShow: (StoryItem storyItem) {
          print('Showing story: ${storyItem.url}');
        },
        progressPosition: ProgressPosition.top,
        repeat: false,
        inline: false,
      ),
    );
  }
}
回到顶部