Flutter 加载 pdf

Flutter 加载 pdf,第1张

Dart async 和 await 超级麻烦

没有阻塞的调用法,即使await, 上层函数 需要 async,还好async有个complete函数,可以用
1.局部变量+complete 完成list的初始化,
2.也因为单线程,没有共享变量的冲突问题。

flutter用的dart 的 异步实在是坑,没有阻塞的调用法。比如future.get()阻塞并且直接取值了,超级方便。但是没有这个,回调callback 很严重。


import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:path_provider/path_provider.dart';

class PdfMenuList extends StatefulWidget {
  const PdfMenuList({Key? key}) : super(key: key);

  @override
  _PdfMenuListState createState() => _PdfMenuListState();
}

class _PdfMenuListState extends State {
  late List pdfBtnList;

  _PdfMenuListState() {
    pdfBtnList = List.of([]);

    var pdfChapters = [
      "1.pdf",
      "2.pdf",
      "3.pdf",
    ];

    for (int i = 0; i < pdfChapters.length; i++) {
      //1.局部变量加complete 传参完成 button list初始化,还好 局部变量有效!!!
      var pdfData;
      rootBundle
          .load("pdf/${pdfChapters[i]}")
          .then((value) => pdfData = value.buffer.asUint8List())
          //2.//局部变量加complete 传参完成 button list初始化,还好 局部变量有效!!!
          .whenComplete(() {
        print("load pdf data over");
        pdfBtnList.add(TextButton(
            onPressed: () {
              getApplicationDocumentsDirectory().then((value) {
                Directory documentsDirectory = value;
                String path = documentsDirectory.path;
                List fileList =
                    Directory(path).listSync(recursive: true);
                for (FileSystemEntity fileSystemEntity in fileList) {
                  print('$fileSystemEntity');
                }
              });

              getExternalStorageDirectory().then((value) {
                print("=================");
                print(value);
                for (var d in value!.listSync(recursive: true)) {
                  print('$d');
                }
              });
              print(pdfChapters[i]);
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) {
                    // return PDFScreen(path: "pdf/$pdfChapters[i]");
                    return PDFScreen(
                      data: pdfData,
                    );
                  },
                ),
              );
            },
            child: Text(pdfChapters[i])));
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    // List paths = List.empty();
    // var path;
    // rootBundle.load("pdf/").then((value) =>
    //   path = value
    // );
    // print(path);

    // var d = Directory("pdf");
    // print(d);
    // print(d.exists());
    // print(getApplicationDocumentsDirectory());

    return Center(
      child: ListView(
        children: pdfBtnList,
      ),
    );
  }
}

class PdfHome extends StatelessWidget {
  const PdfHome({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "PDF Home",
      home: Scaffold(
        appBar: AppBar(
          title: const Text("PDF List"),
        ),
        body: const PdfMenuList(),
      ),
    );
  }
}

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

class PDFScreen extends StatefulWidget {
  //传路径
  final String? path;

  //传二进制数据
  final Uint8List? data;

  const PDFScreen({Key? key, this.path, this.data}) : super(key: key);

  @override
  _PDFScreenState createState() => _PDFScreenState();
}

class _PDFScreenState extends State with WidgetsBindingObserver {
  final Completer _controller =
      Completer();
  int? pages = 0;
  int? currentPage = 0;
  bool isReady = false;
  String errorMessage = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Document"),
        actions: [
          IconButton(
            icon: const Icon(Icons.share),
            onPressed: () {},
          ),
        ],
      ),
      body: Stack(
        children: [
          PDFView(
            // filePath: widget.path,
            pdfData: widget.data,
            enableSwipe: true,
            swipeHorizontal: false,
            autoSpacing: false,
            pageFling: true,
            pageSnap: true,
            defaultPage: currentPage!,
            fitPolicy: FitPolicy.BOTH,
            preventLinkNavigation: false,
            // if set to true the link is handled in 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('goto uri: $uri');
            },
            onPageChanged: (int? page, int? total) {
              print('page change: $page/$total');
              setState(() {
                currentPage = page;
              });
            },
          ),
          errorMessage.isEmpty
              ? !isReady
                  ? const Center(
                      child: CircularProgressIndicator(),
                    )
                  : Container()
              : Center(
                  child: Text(errorMessage),
                )
        ],
      ),
      floatingActionButton: FutureBuilder(
        future: _controller.future,
        builder: (context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            return FloatingActionButton.extended(
              label: Text("Go to ${pages! ~/ 2}"),
              onPressed: () async {
                await snapshot.data!.setPage(pages! ~/ 2);
              },
            );
          }

          return Container();
        },
      ),
    );
  }
}

dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  pdf: ^3.6.1
  #  flutter_pdfview: ^1.2.1
  flutter_pdfview: 1.1.0
  path_provider: ^2.0.6
  http: ^0.13.4

pubspec.yaml:

  assets:
    - pdf/

配置资源文件路径,assets可以配置路径的

 

debug有效release无效?
加载可能比较慢?
还是异步产生了问题?导致桌面模拟器不显示pdf 菜单列表了.
未知?

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/993663.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存