🗒️

【Flutter】pdfビューアーを作る

2025/02/27に公開

使ったパッケージ

今回は以下のパッケージを使用しました。
flutter_pdfview
file_picker

パッケージの追加

pubspec.yamlに以下を追加

dependencies:
  flutter_pdfview: 1.3.2
  file_picker: ^9.0.1

もしくは

flutter pub add flutter_pdfview file_picker

でパッケージを追加します。

スマホ上でPDFファイルを選択して、開く

今回は指定のディレクトリに保存済みのpdfファイルを開くのではなく、スマホ内に保存してあるpdfファイルを選択して開くようにしました。

完成したコードはこちらです。
選択したPDFについては、縦スクロールか横スクロールか事前に選択することで選べるようにしています。

import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PDF Viewer',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'PDF Viewer'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File? file;
  String? _fileName;
  bool _isHorizontal = true;

  Future<void> _pickFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['pdf'],
    );

    if (result != null) {
      setState(() {
        file = File(result.files.single.path!);
        _fileName = result.files.single.name;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(_fileName ?? 'PDF Viewer'),
        actions: [
          DropdownButton<String>(
            value: _isHorizontal ? '横スクロール' : '縦スクロール',
            onChanged: (String? newValue) {
              setState(() {
                _isHorizontal = newValue == '横スクロール';
              });
            },
            items: ['縦スクロール', '横スクロール']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
          ),
        ],
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: ElevatedButton(
              onPressed: _pickFile,
              child: const Text('Pick PDF File'),
            ),
          ),
          Expanded(
            child: file == null
                ? const Center(
                    child: Text('No PDF selected'),
                  )
                : PDFView(
                    filePath: file!.path,
                    enableSwipe: true,
                    swipeHorizontal: _isHorizontal,
                    autoSpacing: false,
                    pageFling: false,
                  ),
          ),
        ],
      ),
    );
  }
}

ファイル選択前

ファイル選択後

Discussion