Search code examples
flutterdartpdf-viewer

How to add a CircularProgressIndicator while navigating to a PDF View Page


In the code below, I am reading a pdf file from my images folder then viewing it in a new page. But when I navigate to the new page it takes time to load the pdf. So, I want to add a CircularProgressIndicator while transitioning. I can't figure out how to do it. How do I add a CircularProgressIndicator widget?

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_full_pdf_viewer/flutter_full_pdf_viewer.dart';

class PdfPage extends StatefulWidget {
  @override
  _PdfPageState createState() => _PdfPageState();
}

class _PdfPageState extends State<PdfPage> {
  Future<String> makeFile() async {

    Directory tempDir = await getTemporaryDirectory();
    String tempPath = tempDir.path;
    File tempFile = File('$tempPath/copy.pdf');
    ByteData bd = await rootBundle.load('images/dummy.pdf');
    await tempFile.writeAsBytes(bd.buffer.asUint8List(), flush: true);
    return tempFile.path;
  }

  bool isLoading = false;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    makeFile().then((value) {
      setState(() {
        path = value;
        print(path);
        //isLoading = false;
      });
    });
  }

  String path;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: RaisedButton(
          child: Text("Open PDF Screen"),
          onPressed: () {
            // CircularProgressIndicator(value: true,);
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => PDFScreen(path)));
          },
        ),
      ),
    );
  }
}

class PDFScreen extends StatelessWidget {
  final String path;
//  final bool isLoading;
  PDFScreen(
    this.path,
  );

  @override
  Widget build(BuildContext context) {
    return PDFViewerScaffold(
        appBar: AppBar(
          title: Text("Scaffold PDF"),
        ),
        path: path);
  }
}



Solution

  • You can use FutureBuilder class which is precisely made for this. That is, some action is expected in the future and you would like to show a progress indicator meanwhile. The action may actually complete or return an error. Futurebuilder lets you handle all these scenarios.

    You can shift makefile() into class PDFScreen and use widget build method to return the FutureBuilder. The simplest implementation is below.

    @override
    Widget build(BuildContext context) {
       return FutureBuilder<String>(
           future: makeFile(),
           builder: (BuildContext context, AsyncSnapshot<String>  snapshot) {
               if (snapshot.connectionState != ConnectionState.done) {
                   return CircularProgressIndicator();
                } else {
                   return PDFViewerScaffold(
                       appBar: AppBar(
                           title: Text("Scaffold PDF"),
                       ),
                       path: snapshot.data
                    );
                }
            },
       );
    }
    

    You might want to visit the official docuementation or this blog on Medium.