Flutter PDF缓存查看插件flutter_cached_pdfview的使用
Flutter PDF缓存查看插件flutter_cached_pdfview的使用
简介
flutter_cached_pdfview
是一个用于在Flutter应用程序中显示PDF文档的插件,支持从路径、资源或URL加载PDF文件,并且可以对URL来源的PDF进行缓存。它具有跨平台特性(iOS和Android),并且即将支持Web端。
插件特性
- 支持从本地路径、资源文件或网络链接加载PDF。
- 支持水平或垂直拖动和缩放。
- 双击放大功能。
- 支持加密PDF文件。
- 可以跳转到指定页码。
- 提供回调函数处理渲染完成、页面切换等事件。
平台支持
- Android (>= API 20)
- iOS (>= 11.0)
安装配置
添加依赖
首先,在pubspec.yaml
文件中添加依赖:
dependencies:
flutter_cached_pdfview: latest_version
然后执行flutter pub get
来安装最新版本的包。
iOS配置
对于iOS项目,需要做以下设置:
- 在项目的
Info.plist
文件中添加键值对:<key>io.flutter.embedded_views_preview</key><true/>
- 修改Podfile文件中的平台版本为
platform :ios, '11.0'
使用示例
下面是一个完整的Demo代码,展示了如何从不同源加载PDF并实现基本交互:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_cached_pdfview/flutter_cached_pdfview.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('flutter_cached_pdfview Demo'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute<dynamic>(
builder: (_) => const PDFViewerFromUrl(
url:
'https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf',
),
),
),
child: const Text('PDF From Url'),
),
TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute<dynamic>(
builder: (_) => const PDFViewerCachedFromUrl(
url:
'https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf',
),
),
),
child: const Text('Cashed PDF From Url'),
),
TextButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute<dynamic>(
builder: (_) => PDFViewerFromAsset(
pdfAssetPath: 'assets/pdf/file-example.pdf',
),
),
),
child: const Text('PDF From Asset'),
),
],
),
);
}
}
// 加载来自URL的PDF
class PDFViewerFromUrl extends StatelessWidget {
const PDFViewerFromUrl({Key? key, required this.url}) : super(key: key);
final String url;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('PDF From Url'),
),
body: const PDF().fromUrl(
url,
placeholder: (double progress) => Center(child: Text('$progress %')),
errorWidget: (dynamic error) => Center(child: Text(error.toString())),
),
);
}
}
// 缓存来自URL的PDF
class PDFViewerCachedFromUrl extends StatelessWidget {
const PDFViewerCachedFromUrl({Key? key, required this.url})
: super(key: key);
final String url;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cached PDF From Url'),
),
body: const PDF().cachedFromUrl(
url,
placeholder: (double progress) => Center(child: Text('$progress %')),
errorWidget: (dynamic error) => Center(child: Text(error.toString())),
),
);
}
}
// 加载来自Assets的PDF
class PDFViewerFromAsset extends StatelessWidget {
PDFViewerFromAsset({Key? key, required this.pdfAssetPath}) : super(key: key);
final String pdfAssetPath;
final Completer<PDFViewController> _pdfViewController = Completer<PDFViewController>();
final StreamController<String> _pageCountController = StreamController<String>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('PDF From Asset'),
actions: <Widget>[
StreamBuilder<String>(
stream: _pageCountController.stream,
builder: (_, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
return Center(
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue[900],
),
child: Text(snapshot.data!),
),
);
}
return const SizedBox();
}),
],
),
body: PDF(
enableSwipe: true,
swipeHorizontal: true,
autoSpacing: false,
pageFling: false,
backgroundColor: Colors.grey,
onPageChanged: (int? current, int? total) =>
_pageCountController.add('${current! + 1} - $total'),
onViewCreated: (PDFViewController pdfViewController) async {
_pdfViewController.complete(pdfViewController);
final int currentPage = await pdfViewController.getCurrentPage() ?? 0;
final int? pageCount = await pdfViewController.getPageCount();
_pageCountController.add('${currentPage + 1} - $pageCount');
},
).fromAsset(
pdfAssetPath,
errorWidget: (dynamic error) => Center(child: Text(error.toString())),
),
floatingActionButton: FutureBuilder<PDFViewController>(
future: _pdfViewController.future,
builder: (_, AsyncSnapshot<PDFViewController> snapshot) {
if (snapshot.hasData && snapshot.data != null) {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FloatingActionButton(
heroTag: '-',
child: const Text('-'),
onPressed: () async {
final PDFViewController pdfController = snapshot.data!;
final int currentPage =
(await pdfController.getCurrentPage())! - 1;
if (currentPage >= 0) {
await pdfController.setPage(currentPage);
}
},
),
FloatingActionButton(
heroTag: '+',
child: const Text('+'),
onPressed: () async {
final PDFViewController pdfController = snapshot.data!;
final int currentPage =
(await pdfController.getCurrentPage())! + 1;
final int numberOfPages =
await pdfController.getPageCount() ?? 0;
if (numberOfPages > currentPage) {
await pdfController.setPage(currentPage);
}
},
),
],
);
}
return const SizedBox();
},
),
);
}
}
通过以上代码,您可以轻松地将PDF集成到您的Flutter应用中,并根据需要选择不同的加载方式。希望这能帮助您更好地理解和使用flutter_cached_pdfview
插件!
更多关于Flutter PDF缓存查看插件flutter_cached_pdfview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter PDF缓存查看插件flutter_cached_pdfview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用flutter_cached_pdfview
插件来缓存和查看PDF文件的示例代码。
首先,确保你已经在pubspec.yaml
文件中添加了flutter_cached_pdfview
依赖:
dependencies:
flutter:
sdk: flutter
flutter_cached_pdfview: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤使用flutter_cached_pdfview
插件:
- 导入必要的包:
import 'package:flutter/material.dart';
import 'package:flutter_cached_pdfview/flutter_cached_pdfview.dart';
import 'package:path_provider/path_provider.dart';
- 创建一个函数来下载并缓存PDF文件:
Future<File> downloadAndCachePdf(String url) async {
final directory = await getApplicationDocumentsDirectory();
final filePath = "${directory.path}/${url.split('/').last}";
final file = File(filePath);
if (!await file.exists()) {
final response = await http.get(Uri.parse(url));
await file.writeAsBytes(response.bodyBytes);
}
return file;
}
- 在你的Widget中使用
CachedPdfView
来显示PDF:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Cached PDF View Example'),
),
body: Center(
child: PdfViewerScreen(),
),
),
);
}
}
class PdfViewerScreen extends StatefulWidget {
@override
_PdfViewerScreenState createState() => _PdfViewerScreenState();
}
class _PdfViewerScreenState extends State<PdfViewerScreen> {
late Future<File> pdfFileFuture;
@override
void initState() {
super.initState();
pdfFileFuture = downloadAndCachePdf('https://example.com/sample.pdf'); // 替换为你的PDF URL
}
@override
Widget build(BuildContext context) {
return FutureBuilder<File>(
future: pdfFileFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('Failed to load PDF');
} else {
final file = snapshot.data!;
return CachedPdfView(
filePath: file.path,
password: null, // 如果PDF有密码,可以在这里提供
onError: (error) {
// 处理加载PDF时发生的错误
print('Error loading PDF: $error');
},
onPageChanged: (page, pageCount) {
// 页面改变时的回调
print('Page changed: $page/$pageCount');
},
onLoad: () {
// PDF加载完成时的回调
print('PDF loaded');
},
);
}
} else {
return CircularProgressIndicator();
}
},
);
}
}
在这个示例中,我们:
- 使用
getApplicationDocumentsDirectory
来获取应用的文档目录,以便缓存PDF文件。 - 使用
http.get
来下载PDF文件,并将其保存到应用的文档目录中。 - 使用
FutureBuilder
来异步加载PDF文件,并在加载完成后使用CachedPdfView
来显示PDF。
请确保在实际项目中处理错误和异常情况,并根据需要调整代码。