说明

flutter_full_pdf_viewer 可以实现从网络上下载 pdf 文件并且显示出来。

包地址:flutter_full_pdf_viewer: ^1.0.6

使用方法

1.在 pubspec.yaml 文件中添加如下的包:

dependencies:
# pdf 阅读器
flutter_full_pdf_viewer: ^1.0.6 # 获取系统目录,因为从网络获取的pdf文件,需要保存到手机,所以需要用到这个包
path_provider: ^1.5.0

2.官方demo:

import 'dart:async';
import 'dart:io'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_full_pdf_viewer/full_pdf_viewer_scaffold.dart';
import 'package:path_provider/path_provider.dart'; void main() {
runApp(MaterialApp(
title: 'Plugin example app',
home: MyApp(),
));
} class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
} class _MyAppState extends State<MyApp> {
String pathPDF = ""; @override
void initState() {
super.initState();
createFileOfPdfUrl().then((f) {
setState(() {
pathPDF = f.path;
print(pathPDF);
});
});
} Future<File> createFileOfPdfUrl() async {
final url = "http://africau.edu/images/default/sample.pdf";
final filename = url.substring(url.lastIndexOf("/") + 1);
var request = await HttpClient().getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
return file;
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Plugin example app')),
body: Center(
child: RaisedButton(
child: Text("Open PDF"),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => PDFScreen(pathPDF)),
),
),
),
);
}
} /// /////////////////////////// 显示 pdf 图文件 //////////////////////////// ///
class PDFScreen extends StatelessWidget {
String pathPDF = ""; PDFScreen(this.pathPDF); @override
Widget build(BuildContext context) {
return PDFViewerScaffold(
appBar: AppBar(
title: Text("Document"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
],
),
path: pathPDF,
);
}
}

3.官方demo 显示效果:

源码解析

主要有两个源码文件,分别是 full_pdf_viewer_plugin.dart 和 full_pdf_viewer_scaffold.dart 文件

1.full_pdf_viewer_plugin.dart

import 'dart:async';
import 'dart:ui'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; enum PDFViewState { shouldStart, startLoad, finishLoad } class PDFViewerPlugin {
final _channel = const MethodChannel("flutter_full_pdf_viewer");
static PDFViewerPlugin _instance; factory PDFViewerPlugin() => _instance ??= new PDFViewerPlugin._();
PDFViewerPlugin._() {
_channel.setMethodCallHandler(_handleMessages);
} final _onDestroy = new StreamController<Null>.broadcast();
Stream<Null> get onDestroy => _onDestroy.stream;
Future<Null> _handleMessages(MethodCall call) async {
switch (call.method) {
case 'onDestroy':
_onDestroy.add(null);
break;
}
} Future<Null> launch(String path, {Rect rect}) async {
final args = <String, dynamic>{'path': path};
if (rect != null) {
args['rect'] = {
'left': rect.left,
'top': rect.top,
'width': rect.width,
'height': rect.height
};
}
await _channel.invokeMethod('launch', args);
} /// Close the PDFViewer
/// Will trigger the [onDestroy] event
Future close() => _channel.invokeMethod('close'); /// adds the plugin as ActivityResultListener
/// Only needed and used on Android
Future registerAcitivityResultListener() =>
_channel.invokeMethod('registerAcitivityResultListener'); /// removes the plugin as ActivityResultListener
/// Only needed and used on Android
Future removeAcitivityResultListener() =>
_channel.invokeMethod('removeAcitivityResultListener'); /// Close all Streams
void dispose() {
_onDestroy.close();
_instance = null;
} /// resize PDFViewer
Future<Null> resize(Rect rect) async {
final args = {};
args['rect'] = {
'left': rect.left,
'top': rect.top,
'width': rect.width,
'height': rect.height
};
await _channel.invokeMethod('resize', args);
}
}

2.full_pdf_viewer_scaffold.dart

其实笔者在实际的使用过程中,是把它提取出来使用的,这样做是为了可以修改源码,让他符合自己的使用场景。当pdf不是全屏显示时,就会遇到状态栏、导航栏高度的问题,可以看笔者写的这篇文章。

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_full_pdf_viewer/full_pdf_viewer_plugin.dart'; class PDFViewerScaffold extends StatefulWidget {
final PreferredSizeWidget appBar;
final String path;
final bool primary; const PDFViewerScaffold({
Key key,
this.appBar,
@required this.path,
this.primary = true,
}) : super(key: key); @override
_PDFViewScaffoldState createState() => new _PDFViewScaffoldState();
} class _PDFViewScaffoldState extends State<PDFViewerScaffold> {
final pdfViwerRef = new PDFViewerPlugin();
Rect _rect;
Timer _resizeTimer; @override
void initState() {
super.initState();
pdfViwerRef.close();
} @override
void dispose() {
super.dispose();
pdfViwerRef.close();
pdfViwerRef.dispose();
} @override
Widget build(BuildContext context) {
if (_rect == null) {
_rect = _buildRect(context);
pdfViwerRef.launch(
widget.path,
rect: _rect,
);
} else {
final rect = _buildRect(context);
if (_rect != rect) {
_rect = rect;
_resizeTimer?.cancel();
_resizeTimer = new Timer(new Duration(milliseconds: 300), () {
pdfViwerRef.resize(_rect);
});
}
}
return new Scaffold(
appBar: widget.appBar,
body: const Center(child: const CircularProgressIndicator()));
} Rect _buildRect(BuildContext context) {
final fullscreen = widget.appBar == null; final mediaQuery = MediaQuery.of(context);
final topPadding = widget.primary ? mediaQuery.padding.top : 0.0;
final top =
fullscreen ? 0.0 : widget.appBar.preferredSize.height + topPadding;
var height = mediaQuery.size.height - top;
if (height < 0.0) {
height = 0.0;
} return new Rect.fromLTWH(0.0, top, mediaQuery.size.width, height);
}
}
原文:http://www.luyixian.cn/news_show_398459.aspx

flutter pdf 文件浏览的更多相关文章

  1. asp.net网页中上传并且浏览pdf文件的实现

    本文主要讲解在asp.net中的gridview中浏览pdf文件.下面来看一下具体的实现: 第一步,使用sqlserver 创建一个数据库表. 第二步,新建一个webform,命名为uploadpdf ...

  2. https://github.com/Lushenggang/show-pdf在线浏览pdf文件在线浏览pdf文件

    在线浏览pdf文件 https://github.com/Lushenggang/show-pdf https://github.com/Lushenggang/show-pdf

  3. web中浏览PDF文件

    1.在web中浏览pdf文件. 2.支持大多数主流浏览器,包括IE8 3.参考网址: https://pdfobject.com/ http://mozilla.github.io/pdf.js/ & ...

  4. WPF 浏览PDF 文件

    添加成功后会在工具箱里看到下图所示的控件.打开VS2010,新建项目(WpfPDFReader),右键项目添加User Control(用户控件).因为Adobe PDF Reader COM 组件是 ...

  5. 在线打开,浏览PDF文件的各种方式及各种pdf插件------(MS OneDrive/google drive & google doc/ github ?raw=true)

    在线打开,浏览PDF文件的各种方式: 1 Google drive&doc   (国内不好使,you know GFW=Great Firewall) 1. google drive: 直接分 ...

  6. 在线浏览pdf文件,pdfobject的简单使用

    该js插件,官网有详细的使用教程(网址:http://www.pdfobject.com/examples/).打开里面的例子后,查看新打开页面,打开并查看该页面的源代码. 需要的材料: 1.PDFo ...

  7. 怎么用ABBYY在线浏览PDF文件

    ABBYY FineReader 让您可以从在线存储服务中打开图像或 PDF 文件,并将已识别文本保存至在线存储服务中,如 Dropbox.SkyDrive 或 Google Drive 等.通过在 ...

  8. C#如何在PDF文件添加图片印章

    文档中添加印章可以起一定的作用,比如,防止文件随意被使用,或者确保文档内容的安全性和权威性.C#添加图片印章其实也有很多实现方法,这里我使用的是免费的第三方软件Free Spire.PDF,向大家阐述 ...

  9. C# 给PDF文件添加水印

      水印种类及功能介绍 PDF水印分为两种:文本水印和图片水印.文本水印一般被用在商业领域,提醒读者该文档是受版权保护的,其他人不能抄袭或者免费使用.除了这个特征,水印还可以用来标记这个文档 的一些基 ...

随机推荐

  1. 委托 事件 observer

    详细介绍http://www.cnblogs.com/jcz1206/articles/2730793.html  ---摘录别人的 using System;using System.Collect ...

  2. python运用 - log信息提取(知识: 遍历 | os )

    运用到的python知识点: excel相关:https://www.cnblogs.com/yaner2018/p/11269873.html 字典: python字典的几种方式: 1)key值遍历 ...

  3. 封装 private

    封装表现: 1.方法就是一个最基本封装体. 2.类其实也是一个封装体. 从以上两点得出结论,封装的好处: 1.提高了代码的复用性. 2.隐藏了实现细节,还要对外提供可以访问的方式.便于调用者的使用.这 ...

  4. springboot中yml常用配置

    server: port: 8080 spring: datasource: #数据源配置 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc: ...

  5. 【C++】C++数据类型

    注意:以下内容摘自文献[1],修改了部分内容. 计算机处理的对象是数据,而数据是以某种特定的形式存在的(例如整数.浮点数.字符等形式).数据结构指的是数据的组织形式.例如,数组就是一种数据结构. 1. ...

  6. [工具-006] C#如何模拟发包登录

    最近接到一个任务,就是模拟某个贴吧的登录发帖功能,我的思路是通过IE浏览器的工具对登陆操作进行抓包,记录登录时候请求的URL,请求方式,请求正文等信息进行模拟的发包. 1.首先我们要到登陆页面,以摇篮 ...

  7. uwsgi+nginx 502 bad get away 错误

    用uwsgi和nginx部署网站时有时候访问网站会出现502错误 配置,启动文件等完全没有问题. 目前解决方法是重启uwsgi就可以了(虽然说502错误应该有很多产生原因啦) 所用命令: $ ps - ...

  8. PowerPC-object与elf中的符号引用

    https://mp.weixin.qq.com/s/6snzjEpDT4uQuCI2Nx9VcQ   一. 符号引用 编译会先把每个源代码文件编译成object目标文件,然后把所有目标文件链接到一起 ...

  9. 【zookeeper】安装教程文档需下载

    请查看文件https://download.csdn.net/download/qq_42158942/11846847 zookeeper的作用 • ZooKeeper 是一个开源的分布式协调服务, ...

  10. Java实现 LeetCode 659 分割数组为连续子序列 (哈希)

    659. 分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [ ...