Flutter文件预览插件files_preview的使用

Flutter文件预览插件files_preview的使用

files_preview 是一个用于在 Flutter 应用程序中预览文件的新插件项目。它包含了针对 Android 和/或 iOS 的平台特定实现代码。

开始使用

项目简介

这个项目是一个 Flutter 插件包的起点,专门包含平台特定的实现代码。对于如何开始 Flutter 开发的帮助,可以查看官方文档,其中提供了教程、示例、移动开发指南以及完整的 API 参考。

示例代码

以下是一个完整的示例,展示了如何使用 files_preview 插件来预览不同类型的文件(如图像、视频、PDF 和音频)。

import 'dart:io';

import 'package:files_preview/common/app_bar.dart';
import 'package:files_preview_example/device_info_utils.dart';
import 'package:files_preview_example/files_preview.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:fluttertoast/fluttertoast.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeScreen(),
    );
  }
}

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

  @override
  // ignore: library_private_types_in_public_api
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _isDownloading = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromARGB(255, 255, 255, 255),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          const AppBarCustom(title: "Files Preview"),
          Expanded(
            child: Stack(
              children: [
                ListView(
                  children: [
                    _buildItem(
                      context,
                      onPressed: () {
                        final name = '9b5784d9e453fc741dfe0cc6aeee7f83ae42.tiff';
                        final path = 'https://tabula-bucket-stg.s3.us-west-2.amazonaws.com/others/9b5784d9e453fc741dfe0cc6aeee7f83ae42.tiff';
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => FilesPreviewScreen(
                              appBarString: name,
                              path: path,
                              openFileSuccess: (success) {
                                if (!success) {
                                  Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                      builder: (context) => FilesPreviewScreen(
                                        appBarString: name,
                                        path: path,
                                      ),
                                    ),
                                  );
                                }
                              },
                            ),
                          ),
                        );
                      },
                      text: "Image Preview",
                    ),
                    _buildItem(
                      context,
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (_) => const FilesPreviewScreen(
                              appBarString: 'bee.mp4',
                              path: 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
                            ),
                          ),
                        );
                      },
                      text: "Video Preview",
                    ),
                    _buildItem(
                      context,
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (_) => const FilesPreviewScreen(
                              appBarString: 'pdf.pdf',
                              path: 'http://www.pdf995.com/samples/pdf.pdf',
                            ),
                          ),
                        );
                      },
                      text: "PDF Preview",
                    ),
                    _buildItem(
                      context,
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => const FilesPreviewScreen(
                              appBarString: 'Opening Themes - Introduction.mp3',
                              path: 'https://scummbar.com/mi2/MI1-CD/01%20-%20Opening%20Themes%20-%20Introduction.mp3',
                            ),
                          ),
                        );
                      },
                      text: "Audio Preview",
                    ),
                    _buildItem(
                      context,
                      onPressed: () {
                        const path = 'https://drive.google.com/file/d/1WARMcVTn29h_VPglToLrXVsqdN7auoK7/view?usp=drive_link';
                        const name = 'Financial.zip';
                        _createFileOfUrl(path, name).then((f) {
                          openFileLocal(context, f.path, (success) async {
                            if (!success) {
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) => FilesPreviewScreen(
                                    appBarString: name,
                                    path: f.path,
                                  ),
                                ),
                              );
                            }
                          });
                        });
                      },
                      text: "Unknow Preview",
                    ),
                  ],
                ),
                if (_isDownloading)
                  Positioned(
                    top: 0,
                    left: 0,
                    right: 0,
                    bottom: 0,
                    child: Container(
                      color: Colors.black12,
                      width: MediaQuery.of(context).size.width,
                      height: MediaQuery.of(context).size.height,
                      child: const Center(
                        child: CircularProgressIndicator(),
                      ),
                    ),
                  ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Future<File> _createFileOfUrl(String path, String name) async {
    setState(() {
      _isDownloading = true;
    });
    Completer<File> completer = Completer<File>();
    if (kDebugMode) {
      print("Start download file from internet!");
    }
    try {
      var request = await HttpClient().getUrl(Uri.parse(path));
      var response = await request.close();
      var bytes = await consolidateHttpClientResponseBytes(response);
      var dir = await getApplicationDocumentsDirectory();
      if (kDebugMode) {
        print("Download files");
      }
      if (kDebugMode) {
        print("${dir.path}/$name");
      }
      File file = File("${dir.path}/$name");

      await file.writeAsBytes(bytes, flush: true);
      completer.complete(file);
    } catch (e) {
      setState(() {
        _isDownloading = false;
      });
      throw Exception('Error parsing asset file!');
    }
    setState(() {
      _isDownloading = false;
    });
    return completer.future;
  }

  Future<void> openFileLocal(BuildContext context, String path, Future<void> Function(bool) callBack) async {
    await _openFile(context, path, (success) => callBack(success));
  }

  Future<void> _openFile(BuildContext context, String path, Future<void> Function(bool) callBack) async {
    if (!File(path).existsSync()) {
      if (kDebugMode) {
        print('[DownloadFileMixin][openFile] File is not existed');
      }
      callBack(false);
      return;
    }
    final isPhysicalDevice = await DeviceInfoUtils.isPhysicalDevice ?? true;
    if (Platform.isIOS && !isPhysicalDevice) {
      if (kDebugMode) {
        print('[DownloadFileMixin][openFile] May crash when open file on Simulator');
      }
      await Fluttertoast.showToast(msg: 'May crash when open file on Simulator');
      callBack(false);
      return;
    }

    // Not open file .apk because do not have permission REQUEST_INSTALL_PACKAGES
    // More information: https://www.youtube.com/watch?v=O0UwUF2DgQc&t=139s
    // If this app needs permission, reopen it again

    if ((await OpenFile.open(path)).type == ResultType.done) {
      callBack(true);
    } else {
      callBack(false);
      Fluttertoast.showToast(msg: "Preview not available");
    }
  }

  Widget _buildItem(context,
      {required String text, required VoidCallback onPressed}) {
    return TextButton(
      style: ButtonStyle(
        padding: MaterialStateProperty.all(
          const EdgeInsets.symmetric(vertical: 25.0, horizontal: 20.0),
        ),
      ),
      onPressed: onPressed,
      child: Text(
        text,
        style: const TextStyle(fontSize: 18.0, fontWeight: FontWeight.w700),
      ),
    );
  }
}

关键组件说明

  • AppBarCustom: 自定义的顶部导航栏。
  • FilesPreviewScreen: 用于预览文件的屏幕。
  • _createFileOfUrl: 下载文件到本地并返回文件对象。
  • _openFile: 打开文件并处理成功或失败的情况。

使用方法

  1. 导入必要的库

    import 'dart:io';
    import 'package:files_preview/common/app_bar.dart';
    import 'package:files_preview_example/device_info_utils.dart';
    import 'package:files_preview_example/files_preview.dart';
    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'package:fluttertoast/fluttertoast.dart';
    import 'package:open_file/open_file.dart';
    import 'package:path_provider/path_provider.dart';
    
  2. 创建主应用类

    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: HomeScreen(),
        );
      }
    }
    
  3. 创建主屏幕类

    class HomeScreen extends StatefulWidget {
      const HomeScreen({super.key});
    
      @override
      _HomeScreenState createState() => _HomeScreenState();
    }
    
    class _HomeScreenState extends State<HomeScreen> {
      bool _isDownloading = false;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: const Color.fromARGB(255, 255, 255, 255),
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              const AppBarCustom(title: "Files Preview"),
              Expanded(
                child: Stack(
                  children: [
                    ListView(
                      children: [
                        _buildItem(
                          context,
                          onPressed: () {
                            final name = '9b5784d9e453fc741dfe0cc6aeee7f83ae42.tiff';
                            final path = 'https://tabula-bucket-stg.s3.us-west-2.amazonaws.com/others/9b5784d9e453fc741dfe0cc6aeee7f83ae42.tiff';
                            Navigator.push(
                              context,
                              MaterialPageRoute(
                                builder: (context) => FilesPreviewScreen(
                                  appBarString: name,
                                  path: path,
                                  openFileSuccess: (success) {
                                    if (!success) {
                                      Navigator.push(
                                        context,
                                        MaterialPageRoute(
                                          builder: (context) => FilesPreviewScreen(
                                            appBarString: name,
                                            path: path,
                                          ),
                                        ),
                                      );
                                    }
                                  },
                                ),
                              ),
                            );
                          },
                          text: "Image Preview",
                        ),
                        // 其他文件预览项...
                      ],
                    ),
                    if (_isDownloading)
                      Positioned(
                        top: 0,
                        left: 0,
                        right: 0,
                        bottom: 0,
                        child: Container(
                          color: Colors.black12,
                          width: MediaQuery.of(context).size.width,
                          height: MediaQuery.of(context).size.height,
                          child: const Center(
                            child: CircularProgressIndicator(),
                          ),
                        ),
                      ),
                  ],
                ),
              ),
            ],
          ),
        );
      }
    }
    

更多关于Flutter文件预览插件files_preview的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件预览插件files_preview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


files_preview 是一个用于在 Flutter 应用中预览文件的插件。它支持多种文件格式,包括 PDF、图片、文本、音频、视频等。通过使用这个插件,开发者可以轻松地在应用中集成文件预览功能。

安装

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

dependencies:
  flutter:
    sdk: flutter
  files_preview: ^1.0.0  # 请检查最新版本

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

基本用法

  1. 导入插件:

    import 'package:files_preview/files_preview.dart';
    
  2. 预览文件:

    你可以使用 FileViewer 组件来预览文件。FileViewer 支持多种文件格式,你可以通过指定 filePathfileBytes 来加载文件。

    例如,预览一个本地文件:

    FileViewer.fromFile(
      filePath: 'assets/sample.pdf',
      onError: (error) {
        print('Error: $error');
      },
    );
    

    或者从网络加载文件:

    FileViewer.fromUrl(
      fileUrl: 'https://example.com/sample.pdf',
      onError: (error) {
        print('Error: $error');
      },
    );
    
  3. 支持的格式:

    files_preview 插件支持以下文件格式:

    • PDF (application/pdf)
    • 图片 (image/png, image/jpeg, image/gif, image/webp)
    • 文本 (text/plain)
    • 音频 (audio/mpeg, audio/ogg, audio/wav)
    • 视频 (video/mp4, video/webm)
  4. 自定义选项:

    你可以通过 FileViewerOptions 来定制文件预览的样式和行为。例如:

    FileViewer.fromFile(
      filePath: 'assets/sample.pdf',
      options: FileViewerOptions(
        enableDownload: true,
        enableShare: true,
        toolbarColor: Colors.blue,
      ),
      onError: (error) {
        print('Error: $error');
      },
    );
    
  5. 错误处理:

    你可以通过 onError 回调来处理文件加载或预览过程中可能发生的错误。

完整示例

以下是一个完整的示例,展示如何在 Flutter 应用中使用 files_preview 插件来预览一个本地 PDF 文件:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('File Preview Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => FileViewer.fromFile(
                    filePath: 'assets/sample.pdf',
                    onError: (error) {
                      print('Error: $error');
                    },
                  ),
                ),
              );
            },
            child: Text('Preview PDF'),
          ),
        ),
      ),
    );
  }
}
回到顶部