Flutter文件查看插件power_file_viewer_v2的使用

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

Flutter文件查看插件power_file_viewer_v2的使用

FlutterMultiFileViewer

A local file preview plugin, using FlutterMultiFileViewer, you can preview doc, docx, ppt, pptx, xls, xlsx, pdf and other files as easily as Android and iOS.

说明

  • Android 使用腾讯TBS服务,支持预览 doc, docx, ppt, pptx, xls, xlsx, pdf, txt, epub 文件
  • iOS 使用 WKWebView,所有WKWebView支持的文件都可以预览

支持的格式

格式 Android iOS
.doc
.docx
.ppt
.pptx
.xls
.xlsx
.pdf

集成

1. 依赖

pubspec.yaml 文件中添加以下依赖:

power_file_viewer_v2: ^1.0.0

2. 快速集成

1. Android

由于使用 Android 的 TBS 服务,需要网络权限和存储权限。

AndroidManifest.xml 文件中添加以下权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

为了防止发布版本加载 TBS 内核库失败,在 proguard-rules.pro 文件中添加以下代码:

-dontwarn dalvik.**
-dontwarn com.tencent.smtt.**

-keep class com.tencent.smtt.** {
    *;
}

-keep class com.tencent.tbs.** {
    *;
}

然后在 build.gradle 中禁用删除无用资源,配置如下图所示:

buildTypes {
    release {
        //关闭删除无用资源
        shrinkResources false
        //关闭删除无用代码
        minifyEnabled false
        zipAlignEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

2. TBS 初始化

由于 Android 使用 TBS 服务,需要在使用前进行初始化,这大约需要3到30秒。

异步初始化(推荐)

可以在应用主函数 main.dart 中执行异步初始化,这样用户打开文件时不需要等待 TBS 初始化。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  FlutterMultiFileViewerManager.initEngine();
  runApp(const MyApp());
}
打开时初始化

如果未进行异步初始化配置,则在打开文件前会自动进行初始化操作,无需额外配置。

4. 快速使用

文件预览

网络文件

只需传递要预览文件的下载URL和下载路径。

定义下载路径:

import 'package:path_provider/path_provider.dart';
...
final _directory = await getTemporaryDirectory();
final downloadPath = "${_directory.path}/fileview/${fileName}.pdf"; // 设置你喜欢的名字
本地文件

只需传递本地文件所在的路径。

class FlutterMultiFileViewerPage extends StatefulWidget {
  final String downloadUrl;
  final String downloadPath;

  const FlutterMultiFileViewerPage({Key? key, required this.downloadUrl, required this.downloadPath}) : super(key: key);

  [@override](/user/override)
  State<FlutterMultiFileViewerPage> createState() => _FlutterMultiFileViewerPageState();
}

class _FlutterMultiFileViewerPageState extends State<FlutterMultiFileViewerPage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text('文件预览'),
      ),
      body: FlutterMultiFileViewerWidget(
        downloadUrl: widget.downloadUrl,
        filePath: widget.downloadPath,
      ),
    );
  }
}
自定义进度显示和错误显示

可以在 loadingBuildererrorBuilder 中自定义进度加载和错误显示样式。

 FlutterMultiFileViewerWidget(
        downloadUrl: widget.downloadUrl,
        filePath: widget.downloadPath,
        loadingBuilder: (viewType, progress) {
          return Container(
            color: Colors.grey,
            alignment: Alignment.center,
            child: Text("加载进度: $progress"),
          );
        },
        errorBuilder: (viewType) {
          return Container(
            color: Colors.red,
            alignment: Alignment.center,
            child: const Text("出错了!!!!"),
          );
        },
      ),

5. HTTP配置(可选)

如果需要使用明文下载,需要进行以下配置

1. Android

android/app/src/main/res/xml 下创建一个新的 network_config.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

并在 android/app/src/main/AndroidManifest.xml 中配置:

<application
       android:networkSecurityConfig="@xml/network_config">

2. iOS

确保在 ios/Runner/Info.plist 中添加以下键值对:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

完整示例

以下是一个完整的示例代码,展示了如何使用 power_file_viewer_v2 插件来预览文件。

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:power_file_view_example/power_file_view_page.dart';
import 'package:power_file_viewer_v2/power_file_view.dart';

import 'permission_util.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  PowerFileViewManager.initLogEnable(true, true);
  PowerFileViewManager.initEngine();
  runApp(const MyApp());
}

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

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

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

const List<String> files = [
  "https://google-developer-training.github.io/android-developer-fundamentals-course-concepts/en/android-developer-fundamentals-course-concepts-en.pdf",
  "http://www.cztouch.com/upfiles/soft/testpdf.pdf",
  "http://blog.java1234.com/cizhi20211008.docx",
  "http://blog.java1234.com/moban20211008.xls"
];

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text('文件列表'),
      ),
      body: ListView.builder(
          itemCount: files.length,
          itemBuilder: (context, index) {
            String filePath = files[index];
            final fileName = FileUtil.getFileName(filePath);
            final fileType = FileUtil.getFileType(filePath);
            return Container(
              margin: const EdgeInsets.only(top: 10.0),
              padding: const EdgeInsets.symmetric(horizontal: 15.0),
              child: ElevatedButton(
                onPressed: () async {
                  String savePath = await getFilePath(fileType, fileName);
                  onTap(context, filePath, savePath);
                },
                child: Text(fileName),
              ),
            );
          }),
    );
  }

  Future onTap(BuildContext context, String downloadUrl, String downloadPath) async {
    bool isGranted = await PermissionUtil.check();
    if (isGranted) {
      Navigator.of(context).push(
        MaterialPageRoute(builder: (ctx) {
          return PowerFileViewPage(
            downloadUrl: downloadUrl,
            downloadPath: downloadPath,
          );
        }),
      );
    } else {
      debugPrint('no permission');
    }
  }

  Future getFilePath(String type, String assetPath) async {
    final _directory = await getTemporaryDirectory();
    return "${_directory.path}/fileview/${base64.encode(utf8.encode(assetPath))}.$type";
  }
}

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

1 回复

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


当然,下面是一个关于如何使用 power_file_viewer_v2 插件的示例代码。这个插件允许你在Flutter应用中查看各种类型的文件。首先,你需要确保你的Flutter项目已经包含了该插件。你可以通过修改 pubspec.yaml 文件来添加依赖:

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

然后运行 flutter pub get 来获取依赖。

接下来,你可以在你的Flutter应用中实现文件查看功能。以下是一个简单的示例,展示如何使用 power_file_viewer_v2 插件来查看一个PDF文件:

import 'package:flutter/material.dart';
import 'package:power_file_viewer_v2/power_file_viewer_v2.dart';
import 'dart:io';

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

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

class FileViewerScreen extends StatefulWidget {
  @override
  _FileViewerScreenState createState() => _FileViewerScreenState();
}

class _FileViewerScreenState extends State<FileViewerScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('File Viewer Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _openFile,
          child: Text('Open PDF File'),
        ),
      ),
    );
  }

  Future<void> _openFile() async {
    // 这里你需要有一个实际的文件路径,例如从设备存储中选择的文件
    // 这里我们使用一个硬编码的路径作为示例,实际使用时需要替换为真实的文件路径
    String filePath = 'path/to/your/file.pdf'; // 请替换为实际的文件路径

    // 检查文件是否存在
    File file = File(filePath);
    if (!await file.exists()) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('File does not exist')),
      );
      return;
    }

    // 打开文件查看器
    try {
      await PowerFileViewer.open(
        filePath: filePath,
        fileType: PowerFileType.pdf, // 根据文件类型设置,例如:.doc, .docx, .xls, .xlsx, .ppt, .pptx, .txt, .jpg, .jpeg, .png, .gif, .bmp, .mp4, .mp3, .pdf 等
        pageNavigation: true, // 是否允许页面导航(仅适用于PDF)
        zoom: true, // 是否允许缩放
        autoPlay: true, // 是否自动播放(仅适用于视频)
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Failed to open file: $e')),
      );
    }
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮,当用户点击该按钮时,将尝试打开一个指定的PDF文件。你需要将 filePath 替换为实际的文件路径。

注意:

  1. PowerFileType 枚举包含了支持的文件类型,你需要根据你要打开的文件类型设置相应的值。
  2. 确保你的应用具有访问设备存储的权限,特别是当你尝试打开用户设备上的文件时。

这个示例仅展示了如何打开PDF文件,你可以根据需要修改代码以支持其他类型的文件。插件的文档通常会提供关于支持的文件类型和更多配置选项的详细信息。

回到顶部