Flutter PDF阅读插件uc_pdfview的使用
Flutter PDF阅读插件uc_pdfview的使用
uc_pdfview
是一个基于 Flutter 的 PDF 查看插件,支持 iOS 和 Android 平台。它提供了丰富的功能和选项,帮助开发者轻松集成 PDF 查看功能到 Flutter 应用中。以下是关于如何使用 uc_pdfview
插件的详细说明,并附带一个完整的示例代码。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 uc_pdfview
依赖:
dependencies:
uc_pdfview: ^0.0.1
然后,通过命令行安装依赖:
flutter packages get
2. 设置
iOS 设置
对于 iOS,需要在 Info.plist
文件中添加以下键值对,以启用嵌入式视图预览:
<key>io.flutter.embedded_views_preview</key>
<true/>
3. 导入库
在 Dart 代码中导入 uc_pdfview
:
import 'package:uc_pdfview/uc_pdfview.dart';
4. 配置选项
UCPDFView
提供了多个配置选项,用于自定义 PDF 查看器的行为。以下是一些常用的选项及其默认值:
名称 | Android | iOS | 默认值 |
---|---|---|---|
defaultPage | ✅ | ✅ | 0 |
onViewCreated | ✅ | ✅ | null |
onRender | ✅ | ✅ | null |
onPageChanged | ✅ | ✅ | null |
onError | ✅ | ✅ | null |
onPageError | ✅ | ❌ | null |
onLinkHandle | ✅ | ✅ | null |
gestureRecognizers | ✅ | ✅ | null |
filePath | ✅ | ✅ | |
pdfData | ✅ | ✅ | |
fitPolicy | ✅ | ❌ | FitPolicy.WIDTH |
enableSwipe | ✅ | ✅ | true |
swipeHorizontal | ✅ | ✅ | false |
password | ✅ | ✅ | null |
nightMode | ✅ | ❌ | false |
autoSpacing | ✅ | ✅ | true |
pageFling | ✅ | ✅ | true |
pageSnap | ✅ | ❌ | true |
preventLinkNavigation | ✅ | ✅ | false |
5. 控制器选项
PDFViewController
提供了一些方法来控制 PDF 查看器的行为:
名称 | 描述 | 参数 | 返回值 |
---|---|---|---|
getPageCount | 获取总页数 | - | Future<int> |
getCurrentPage | 获取当前页数 | - | Future<int> |
setPage | 跳转到指定页数 | int page | Future<bool> |
6. 示例代码
以下是一个完整的示例代码,展示了如何使用 uc_pdfview
插件来查看本地和远程 PDF 文件。
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:uc_pdfview/uc_pdfview.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String pathPDF = "";
String landscapePathPdf = "";
String remotePDFpath = "";
String corruptedPathPDF = "";
@override
void initState() {
super.initState();
// 加载本地 PDF 文件
fromAsset('assets/corrupted.pdf', 'corrupted.pdf').then((f) {
setState(() {
corruptedPathPDF = f.path;
});
});
fromAsset('assets/demo-link.pdf', 'demo.pdf').then((f) {
setState(() {
pathPDF = f.path;
});
});
fromAsset('assets/demo-landscape.pdf', 'landscape.pdf').then((f) {
setState(() {
landscapePathPdf = f.path;
});
});
// 下载远程 PDF 文件
createFileOfPdfUrl().then((f) {
setState(() {
remotePDFpath = f.path;
});
});
}
// 从网络下载 PDF 文件并保存到本地
Future<File> createFileOfPdfUrl() async {
Completer<File> completer = Completer();
print("开始从互联网下载文件!");
try {
final url = "http://www.pdf995.com/samples/pdf.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);
var dir = await getApplicationDocumentsDirectory();
print("下载文件路径: ${dir.path}/$filename");
File file = File("${dir.path}/$filename");
await file.writeAsBytes(bytes, flush: true);
completer.complete(file);
} catch (e) {
throw Exception('解析资产文件时出错!');
}
return completer.future;
}
// 从 assets 中加载 PDF 文件
Future<File> fromAsset(String asset, String filename) async {
Completer<File> completer = Completer();
try {
var dir = await getApplicationDocumentsDirectory();
File file = File("${dir.path}/$filename");
var data = await rootBundle.load(asset);
var bytes = data.buffer.asUint8List();
await file.writeAsBytes(bytes, flush: true);
completer.complete(file);
} catch (e) {
throw Exception('解析资产文件时出错!');
}
return completer.future;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter PDF View',
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const Text('PDF 查看器示例')),
body: Center(
child: Column(
children: <Widget>[
TextButton(
child: Text("打开 PDF"),
onPressed: () {
if (pathPDF.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PDFScreen(path: pathPDF),
),
);
}
},
),
TextButton(
child: Text("打开横向 PDF"),
onPressed: () {
if (landscapePathPdf.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PDFScreen(path: landscapePathPdf),
),
);
}
},
),
TextButton(
child: Text("打开远程 PDF"),
onPressed: () {
if (remotePDFpath.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PDFScreen(path: remotePDFpath),
),
);
}
},
),
TextButton(
child: Text("打开损坏的 PDF"),
onPressed: () {
if (corruptedPathPDF.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PDFScreen(path: corruptedPathPDF),
),
);
}
},
)
],
),
),
),
);
}
}
class PDFScreen extends StatefulWidget {
final String? path;
PDFScreen({Key? key, this.path}) : super(key: key);
_PDFScreenState createState() => _PDFScreenState();
}
class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
final Completer<PDFViewController> _controller = Completer<PDFViewController>();
int? pages = 0;
int? currentPage = 0;
bool isReady = false;
String errorMessage = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("文档"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
],
),
body: Stack(
children: <Widget>[
UCPDFView(
filePath: widget.path,
enableSwipe: true,
swipeHorizontal: true,
autoSpacing: false,
pageFling: true,
pageSnap: true,
defaultPage: currentPage!,
fitPolicy: FitPolicy.BOTH,
preventLinkNavigation: false, // 如果设置为 true,则链接由 Flutter 处理
onRender: (_pages) {
setState(() {
pages = _pages;
isReady = true;
});
},
onError: (error) {
setState(() {
errorMessage = error.toString();
});
print(error.toString());
},
onPageError: (page, error) {
setState(() {
errorMessage = '$page: ${error.toString()}';
});
print('$page: ${error.toString()}');
},
onViewCreated: (PDFViewController pdfViewController) {
_controller.complete(pdfViewController);
},
onLinkHandler: (String? uri) {
print('跳转到 URI: $uri');
},
onPageChanged: (int? page, int? total) {
print('页面变化: $page/$total');
setState(() {
currentPage = page;
});
},
),
errorMessage.isEmpty
? !isReady
? Center(
child: CircularProgressIndicator(),
)
: Container()
: Center(
child: Text(errorMessage),
)
],
),
floatingActionButton: FutureBuilder<PDFViewController>(
future: _controller.future,
builder: (context, AsyncSnapshot<PDFViewController> snapshot) {
if (snapshot.hasData) {
return FloatingActionButton.extended(
label: Text("跳转到 ${pages! ~/ 2}"),
onPressed: () async {
await snapshot.data!.setPage(pages! ~/ 2);
},
);
}
return Container();
},
),
);
}
}
7. 生产环境使用
如果你使用 ProGuard,确保包含以下行:
-keep class com.shockwave.**
更多关于Flutter PDF阅读插件uc_pdfview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter PDF阅读插件uc_pdfview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用uc_pdfview
插件来展示PDF文件的示例代码。uc_pdfview
是一个流行的Flutter插件,用于在应用中嵌入和显示PDF文档。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加uc_pdfview
的依赖:
dependencies:
flutter:
sdk: flutter
uc_pdfview: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
2. 导入插件
在你的Dart文件中导入uc_pdfview
插件:
import 'package:flutter/material.dart';
import 'package:uc_pdfview/uc_pdfview.dart';
3. 使用PDFView组件
下面是一个完整的示例,展示了如何使用PDFView
组件来显示PDF文件:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter PDF Reader',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PDFViewerScreen(),
);
}
}
class PDFViewerScreen extends StatefulWidget {
@override
_PDFViewerScreenState createState() => _PDFViewerScreenState();
}
class _PDFViewerScreenState extends State<PDFViewerScreen> {
@override
Widget build(BuildContext context) {
// 本地PDF文件路径(可以是从网络下载或本地资源)
final String pdfUrl = 'assets/sample.pdf'; // 确保在pubspec.yaml中声明了assets
return Scaffold(
appBar: AppBar(
title: Text('PDF Viewer'),
),
body: Center(
child: PDFView(
filePath: pdfUrl,
password: null, // 如果PDF文件有密码,可以在这里提供
autoSpacing: false,
pageFling: true,
swipeHorizontal: true,
pageSnap: true,
nightMode: false,
autoScroll: false,
defaultPage: 0,
onError: (error) {
// 处理加载PDF文件时的错误
print('Error loading PDF: $error');
},
onRender: (_) {
// PDF文件渲染完成时的回调
print('PDF rendered');
},
onPageChanged: (page) {
// 页面改变时的回调
print('Page changed to: $page');
},
onProgress: (progress) {
// 加载进度回调
print('Loading progress: $progress');
},
),
),
);
}
}
4. 在pubspec.yaml
中声明assets
如果你的PDF文件是放在assets
文件夹中的,你需要在pubspec.yaml
文件中声明它:
flutter:
assets:
- assets/sample.pdf
注意事项
- 确保你的PDF文件路径是正确的。如果是从网络加载,可以直接使用URL。
uc_pdfview
插件依赖于原生组件,因此需要在iOS和Android平台上进行一些配置,但大多数情况下,插件会自动处理这些配置。- 根据你的需求,你可以调整
PDFView
组件的各种参数,如是否启用夜间模式、是否自动滚动等。
这样,你就可以在Flutter应用中展示PDF文件了。如果有任何问题或需要进一步的自定义,请参考uc_pdfview
的官方文档。