本地PDF阅读主要使用到以下两个插件:
flutter_pdfview:提供多种关于pdf文档的操作方法。详细请见:https://github.com/endigo/flutter_pdfview
path_provider:提供获取用户存储文件路径的方法。
主要的思路很简单;
1 读取assets中的pdf文档到内存中;
1.1 在assets文档中添加本地的pdf文档;
1.2 创建获取assets中文件的方法;
//提供方法获取pdf文档内容
Future getfileFromAssets(String fileas) async {
try {
//获取file中的数据
var data = await rootBundle.load(fileas);
//将数据转为byte类型的数据
var byte = data.buffer.asUint8List();
//存储数据路径
var dir = await getApplicationDocumentsDirectory();
File file = File("${dir.path}/mypdf.pdf");
//将数据写入file中
File assetFile = await file.writeAsBytes(byte);
return assetFile;
} catch (e) {
print(e.toString());
}
}
2 使用插件中的方法读取pdf对应内容;
2.1 创建pdf展示界面,并提供翻页按键:
//具体的pdf页面的设置
class PdfPage extends StatefulWidget {
final String path;
const PdfPage({Key key, this.path}) : super(key: key);
@override
_PdfPageState createState() => _PdfPageState();
}
class _PdfPageState extends State {
int totalpages = 0;
bool pdfready = false;
PDFViewController pdfviewController;
var _currentPage = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("my doc"),
),
body: Stack(
children: [
PDFView(
filePath: widget.path,
autoSpacing: true,
enableSwipe: true,
swipeHorizontal: true,
onRender: (_pages) {
setState(() {
totalpages = _pages;
pdfready = true;
});
},
onViewCreated: (PDFViewController vc) {
pdfviewController = vc;
},
onPageChanged: (int page, int total) {
setState(() {
_currentPage = page;
totalpages = total;
});
},
),
!pdfready? Center(
child: CircularProgressIndicator(),
)
: Offstage()
],
),
floatingActionButton: Row(
children: [
_currentPage > 0? FloatingActionButton.extended(
onPressed: () {
_currentPage -= 1;
pdfviewController.setPage(_currentPage);
},
label: Text("Go to ${_currentPage - 1}"),
backgroundColor: Colors.red,
)
: Offstage(),
_currentPage < totalpages - 1
? FloatingActionButton.extended(
onPressed: () {
_currentPage += 1;
pdfviewController.setPage(_currentPage);
},
label: Text("Go to ${_currentPage + 1}"),
backgroundColor: Colors.green,
)
: Offstage(),
],
),
);
}
}
2.2设置按键跳转:
Navigator.push(context,MaterialPageRoute(
builder: (context) => PdfPage(path: assetpath),
))
完整代码如下:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
//pdf阅读器
class PdfView extends StatefulWidget {
@override
_PdfViewState createState() => _PdfViewState();
}
class _PdfViewState extends State {
String assetfile = "files/testpdf.pdf";
String assetpath = "";
@override
void initState() {
super.initState();
//获取assetfile文件 并将其path赋值给assetpath
getfileFromAssets(assetfile).then((f) {
setState(() {
assetpath = f.path;
});
});
}
//提供方法获取pdf文档内容
Future getfileFromAssets(String fileas) async {
try {
//获取file中的数据
var data = await rootBundle.load(fileas);
//将数据转为byte类型的数据
var byte = data.buffer.asUint8List();
//存储数据路径
var dir = await getApplicationDocumentsDirectory();
File file = File("${dir.path}/mypdf.pdf");
//将数据写入file中
File assetFile = await file.writeAsBytes(byte);
return assetFile;
} catch (e) {
print(e.toString());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("pdf reader"),
),
body: Column(
children: [
RaisedButton(
onPressed: () {
if (assetpath != null) {
Navigator.push(context,MaterialPageRoute(
builder: (context) => PdfPage(path: assetpath),
));
}
},
child: Text("file from assets")),
],
),
);
}
}
//具体的pdf页面的设置
class PdfPage extends StatefulWidget {
final String path;
const PdfPage({Key key, this.path}) : super(key: key);
@override
_PdfPageState createState() => _PdfPageState();
}
class _PdfPageState extends State {
int totalpages = 0;
bool pdfready = false;
PDFViewController pdfviewController;
var _currentPage = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("my doc"),
),
body: Stack(
children: [
PDFView(
filePath: widget.path,
autoSpacing: true,
enableSwipe: true,
swipeHorizontal: true,
onRender: (_pages) {
setState(() {
totalpages = _pages;
pdfready = true;
});
},
onViewCreated: (PDFViewController vc) {
pdfviewController = vc;
},
onPageChanged: (int page, int total) {
setState(() {
_currentPage = page;
totalpages = total;
});
},
),
!pdfready? Center(
child: CircularProgressIndicator(),
)
: Offstage()
],
),
floatingActionButton: Row(
children: [
_currentPage > 0? FloatingActionButton.extended(
onPressed: () {
_currentPage -= 1;
pdfviewController.setPage(_currentPage);
},
label: Text("Go to ${_currentPage - 1}"),
backgroundColor: Colors.red,
)
: Offstage(),
_currentPage < totalpages - 1
? FloatingActionButton.extended(
onPressed: () {
_currentPage += 1;
pdfviewController.setPage(_currentPage);
},
label: Text("Go to ${_currentPage + 1}"),
backgroundColor: Colors.green,
)
: Offstage(),
],
),
);
}
}