Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cant Change pdfData from setState #136

Open
kttary opened this issue Apr 10, 2021 · 2 comments
Open

Cant Change pdfData from setState #136

kttary opened this issue Apr 10, 2021 · 2 comments

Comments

@kttary
Copy link

kttary commented Apr 10, 2021

I fill PDFView version ^1.1.0 with pdfData and i want to change the pdfData later by means of setState. Unfortunately the PDFView doesnt changed. Here is my code:

import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';

import 'package:flutter/services.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';

import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';

class PdfViewTest extends StatefulWidget {

  final Uint8List data;
  PdfViewTest({Key key = const Key("PdfView Test"), required this.data}) : super(key: key);

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

class _PdfViewTestState extends State<PdfViewTest> {
  Uint8List? pdfData;

  @override
  void initState() {
    pdfData = widget.data;
    super.initState();
  }

  Future<void> fromAssetToData(String asset, String filename) async {
    Completer<Uint8List> completer = Completer();

    try {
      var dir = await getApplicationDocumentsDirectory();
      var data = await rootBundle.load(asset);
      Uint8List bytes = data.buffer.asUint8List();

      setState(() {
        pdfData = bytes;
      });
    } catch (e) {
      throw Exception('Error parsing asset file!');
    }
  }

  @override
  Widget build(BuildContext context) {
    final Completer<PDFViewController> _controller = Completer<PDFViewController>();
    int pages = 0;
    int currentPage = 0;
    bool isReady = false;
    String errorMessage = '';

    return
      Scaffold(
          appBar: AppBar(
            title: Text("PDF Viewer"),
          ),
          body: PDFView(
            pdfData: pdfData,
            enableSwipe: true,
            swipeHorizontal: true,
            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);
            },
          ),
          persistentFooterButtons: [
            Container(
              width: MediaQuery.of(context).copyWith().size.width,
              child: Row(
                children: [
                  Expanded(
                    child: TextButton(
                      child: Text('Open Demo'),
                      onPressed: (){
                        fromAssetToData('assets/demo-link.pdf', 'demo.pdf');
                      },
                    ),
                  )
                ],
              ),
            )
          ]
      );
  }
}

i call PdfViewTest from other screen as follow:

ElevatedButton(
      child: Text("Scan"),
      onPressed: () {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => PdfViewTest(data: initPdfData!)),
      );
}),

and the initPdfData is populated on initState:

Uint8List? initPdfData;

@override
  void initState() {
    super.initState();

    fromAsset('assets/demo-landscape.pdf', 'demo-landscape.pdf').then((f) {
    });
}

Future<void> fromAsset(String asset, String filename) async {
    Completer<File> completer = Completer();

    try {
      var dir = await getApplicationDocumentsDirectory();
      File file = File("${dir.path}/$filename");
      var data = await rootBundle.load(asset);
      initPdfData = data.buffer.asUint8List();
    } catch (e) {
      throw Exception('Error parsing asset file!');
    }

  }
@shinxxxxwon
Copy link

Did you solve this problem?

@maurojohann
Copy link

Did you solve this problem?

add a key to the pdfViewer widget, this will make the build method recognize that this widget has also been changed and needs to be repainted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants