【やりたい事】
- PDFを表示したい
- いろいろな方法で表示してみる
【環境】
Flutter 3.7.7
Dart 2.19.4
【試したパッケージ】
【flutter_pdfview】
このパッケージの実装としては生のPDFを画面に表示させています。
pdfDataはAPIを叩いてレスポンスを返してもらっています。
中身としてはAmzonS3のfilePathが入っていて、pdfDataにresponseのbodyBytesを入れています。
サンプルコードは下記になります。
class PDFView extends StatefulWidget {
final Uint8List pdfData;
PDFView({Key? key, required this.pdfData}) : super(key: key);
_PDFView createState() => _PDFView(pdfData: pdfData,);
}
class _PDFView extends State<PDFView> {
_PDFView({required this.pdfData});
final Uint8List pdfData;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
PDFView(
pdfData: pdfData,
enableSwipe: true,
swipeHorizontal: true,
autoSpacing: false,
pageFling: true,
pageSnap: true,
defaultPage: 0,
fitPolicy: FitPolicy.BOTH,
preventLinkNavigation: false,
onRender: (_pages) {
//読み込み中の処理
},
onError: (error) {
// 読み込みエラー時の処理
},
),
_closeButton(context),
],
),
);
}
Widget _closeButton(BuildContext context) {
return Positioned(
top: 45,
right: 20,
child: GestureDetector(
onTap: () => Navigator.of(context).pop(true),
child: Container(
child: Icon(
Icons.close,
size: 25,
),
)),
);
}
}
*状態管理をProviderやRiverPodでされる方はご自身で編集して下さい。
flutter_pdfviewを利用してPDFの表示はできたのですが、デバックコンソールに大量のログが出力されました。
[Unknown process name] Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.
[Unknown process name] If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental variable.
上記が何度も繰り返し出力されます。
調べるとCoreGraphicsはiOSやmacOSでの描画を行うためのフレームワークで、不正な数値(NaN、または非数)をCoreGraphics APIに渡しているために出力されている。
描画に問題が発生する可能性がある。
この問題はfultter_pdfviewのGitHubにあるIssuesにも書かれており、2023年9月13日時点では未解決です。
環境
fultter_pdfview 1.3.1
flutter 3.7.7
iOS 16.1
【pdfx】
このパッケージの実装はURLを使ってPDFを表示しています。
ただしinternet_fileというパッケージを追加で入れる必要があります。
pathはAPIを叩いてレスポンスを返してもらっています。
中身としてはAmzonS3のfilePathをpathに入れています。
サンプルコードは下記になります。
class PDFView extends StatefulWidget {
final String path;
PDFView({Key? key, required this.path, }) : super(key: key);
_PDFView createState() => _PDFView(path: path);
}
class _PDFView extends State<PDFPage> {
_PDFView({required this.path});
final String path;
late PdfController _pdfController;
void _initFunction() {
String _pdfUrl =
'http://sample.s3.ap-northeast1.amazonaws.com/' + path;
_pdfController = PdfController(
document: PdfDocument.openData(InternetFile.get(_pdfUrl)),
initialPage: 1,
);
}
@override
void initState() {
super.initState();
_initFunction();
}
@override
void dispose() {
_pdfController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
PdfView(
builders: PdfViewBuilders<DefaultBuilderOptions>(
options: const DefaultBuilderOptions(),
documentLoaderBuilder: (_) => // 読み込み中の処理
pageLoaderBuilder: (_) => // 読み込み中の処理
),
controller: _pdfController,
),
_closeButton(context),
],
),
);
}
Widget _closeButton(BuildContext context) {
return Positioned(
top: 45,
right: 20,
child: GestureDetector(
onTap: () => Navigator.of(context).pop(true),
child: Container(
child: Icon(
Icons.close,
size: 25,
),
)),
);
}
}
*状態管理をProviderやRiverPodでされる方はご自身で編集して下さい。
こちらは特に問題もなく正常に動いています。
【最後に】
FlutterではPDFのパッケージが沢山用意されています。
どれを使えばいいのか分からないですよね。
今回は生のPDFとURLからの二通りをやってみましたので参考になれば幸いです。
参考サイト