如何将native_pdf_view集成到我的应用中(颤振)?

时间:2020-09-13 17:12:23

标签: flutter dart

我想在我的应用中显示一个带有native_pdf_view(https://pub.dev/packages/native_pdf_view)包的PDF文件。

我这样尝试过:

class OStundenplan extends StatelessWidget {

  final pdfController = PdfController(
    document: PdfDocument.openAsset('assets/stundenplan.pdf'),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Offline Stundenplan'),
        ),
        body: Builder(builder: (BuildContext context) {
          return PdfView(controller: _pdfController);
        }));
  }
}

  ostundenplan() {
    Navigator.push(
        context,
        MaterialPageRoute(
            Widget pdfView() => PdfView(
      controller: pdfController,
    );
  }

稍后在应用中:

RaisedButton.icon(onPressed: ostundenplan, icon: Icon(Icons.signal_wifi_off), label: Text('Offline Stundenplan'),),

但不起作用。谁能帮我吗?

编辑:

当我像pradyot1996所说的那样尝试时,我得到了:

Compiler message:
lib/main.dart:315:37: Error: Type 'PDFReader' not found.
class _PDFReaderState extends State<PDFReader> {
                                    ^^^^^^^^^
lib/main.dart:315:7: Error: Type argument 'invalid-type' doesn't conform to the bound 'StatefulWidget' of the type variable 'T' on 'State' in the supertype 'State' of class '_PDFReaderState'.
 - 'StatefulWidget' is from 'package:flutter/src/widgets/framework.dart' ('/C:/flutter/packages/flutter/lib/src/widgets/framework.dart').
Try changing type arguments so that they conform to the bounds.
class _PDFReaderState extends State<PDFReader> {
      ^
/C:/flutter/packages/flutter/lib/src/widgets/framework.dart:1029:22: Context: This is the type variable whose bound isn't conformed to.
abstract class State<T extends StatefulWidget> with Diagnosticable {
                     ^

Compiler message:
lib/main.dart:315:37: Error: Type 'PDFReader' not found.
class _PDFReaderState extends State<PDFReader> {
                                    ^^^^^^^^^
lib/main.dart:315:7: Error: Type argument 'invalid-type' doesn't conform to the bound 'StatefulWidget' of the type variable 'T' on 'State' in the supertype 'State' of class '_PDFReaderState'.
 - 'StatefulWidget' is from 'package:flutter/src/widgets/framework.dart' ('/C:/flutter/packages/flutter/lib/src/widgets/framework.dart').
Try changing type arguments so that they conform to the bounds.
class _PDFReaderState extends State<PDFReader> {
      ^
/C:/flutter/packages/flutter/lib/src/widgets/framework.dart:1029:22: Context: This is the type variable whose bound isn't conformed to.
abstract class State<T extends StatefulWidget> with Diagnosticable {
                     ^
Target kernel_snapshot failed: Exception: Errors during snapshot creation: null
build failed.
                   ^^^^^^^^^^

好像找不到PDFReader。 我该怎么办?

编辑2:

这是我得到的红色屏幕: Error screen

顺便说一句,这是我的导航器:

  ostundenplan() {
    Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => PDFReader()));
  }

编辑3:

class PDFReader extends StatefulWidget {
  static const route_name = 'pdf_reader';

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

class _PDFReaderState extends State<PDFReader> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Offline Stundenplan'),
      ),
      body: FutureBuilder(
        future: PDFDocument.fromAsset('assets/stundenplan.pdf'),
        builder: (_, pdfData) {},
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:3)

enter image description here试试这个软件包flutter_plugin_pdf_viewer

这对我来说很好用。我将PDF文件保存在Firebase存储器中,并通过URL打开。

PDFDocument doc = await PDFDocument.fromURL(LINK);

PDFViewer(document: doc)

编辑:

下面的类显示了实现。如果您不需要刷新状态,甚至可以使用StatelessWidget类。

class PDFReader extends StatefulWidget {
  static const route_name = 'pdf_reader';

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

class _PDFReaderState extends State<PDFReader> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Document'),
      ),
      body: FutureBuilder(
        future: PDFDocument.fromURL('http://www.africau.edu/images/default/sample.pdf'),
        builder: (_, pdfData) {
          if (pdfData.connectionState == ConnectionState.waiting) {
            return CenterCircularProgressBar();
          } else if (pdfData.data == null) {
            return CenterText('Not able to open PDF file');
          } else {
            return PDFViewer(document: pdfData.data);
          }
        },
      ),
    );
  }
}

现在,您只需要导航到PDFReader小部件。如果要将PDF数据从一个屏幕传递到另一个屏幕,也可以执行此操作,而不是在PDFReader屏幕中对其进行硬编码。

CenterCircularProgressBar()是一个自定义窗口小部件,它显示一个通告 屏幕中心的进度条,直到加载PDF 和, CenterText是一个自定义小部件,如果我们没有得到该小部件,则会显示错误 数据从PDFDocument.fromURL返回。代码如下。

所以在这一行

PDFDocument.fromURL('http://www.africau.edu/images/default/sample.pdf')

您可以使用PDFDocument提供的fromAsset,fromURL和fromFile方法来显示PDF。 PDFViewer是程序包提供的自定义类,它将处理PDF视图。

class CenterCircularProgressBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const Center(
      child: CircularProgressIndicator(),
    );
  }
}

class CenterText extends StatelessWidget {
  final String stringValue;

  CenterText(this.stringValue);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        stringValue,
      ),
    );
  }
}

答案 1 :(得分:0)

如果你想用原始库“(https://pub.dev/packages/native_pdf_view)”来做,你可以这样做:

  • 如果您想与 PDF 交互,则需要使用有状态小部件。 (假设您的 PDF 超过 1 页)

  • 当您调用 PdfView 时,请记住包含文档和控制器。 (您在 PdfView 的构造函数中缺少资产路径)。

      PdfView(
       controller: _pdfController,
          onDocumentLoaded: (document) {
            setState(() {
              _allPagesCount = document.pagesCount;
            });
          },
          onPageChanged: (page) {
            setState(() {
              _actualPageNumber = page;
            });
          },
       ),
    

以上代码摘自原始库示例:https://pub.dev/packages/native_pdf_view/example

所以你的代码应该是这样的:

ostundenplan() {
Navigator.push(
    context,
    MaterialPageRoute(
        Widget pdfView() => PdfView(
         controller: pdfController,
         onDocumentLoaded: (document) {
          setState(() {
            _allPagesCount = document.pagesCount;
          });
        },
        onPageChanged: (page) {
          setState(() {
            _actualPageNumber = page;
          });
        },
     ),
  );
 }

在类的顶部添加这些变量:

int _actualPageNumber = _initialPage, _allPagesCount = 0;

这可以帮助您,而无需更改您的初始库。