Typ 'Future <Uint8List>' ist kein Subtyp vom Typ 'Widget'

Aug 18 2020

Ich versuche, mit dieser Schaltfläche in meiner Flatter-App ein PDF anzuzeigen, erhalte jedoch weiterhin den Fehler im Titel

  AppButton.buildAppButton(
                  context,
                  AppButtonType.TEXT_OUTLINE,
                  'Generate PDF',
                  Dimens.BUTTON_BOTTOM_DIMENS, onPressed: () {
                Sheets.showAppHeightEightSheet(
                context: context,
                  widget: work(),
                );
              })

Dies ist mein Arbeits-Widget

      Widget work() {
       dynamic pdf =  generateInvoice(PdfPageFormat.a4);
       return pdf;
     }

welches diese Funktion aufruft. Ich erhalte jedoch immer wieder den Titelfehlertyp 'Future' ist kein Subtyp vom Typ 'Widget'. Jede Hilfe wird geschätzt. Endziel ist es, das PDF anzusehen, aber ich bin mir nicht sicher, wie ich dorthin komme. Vielen Dank!

Future<Uint8List> generateInvoice(PdfPageFormat pageFormat) async {
  final lorem = pw.LoremText();

  final products = <Product>[
    Product('19874', lorem.sentence(4), 3.99, 2),
    Product('98452', lorem.sentence(6), 15, 2),
    Product('28375', lorem.sentence(4), 6.95, 3),
    Product('95673', lorem.sentence(3), 49.99, 4),
    Product('23763', lorem.sentence(2), 560.03, 1),
    Product('55209', lorem.sentence(5), 26, 1),
    Product('09853', lorem.sentence(5), 26, 1),
   
  ];

  final invoice = Invoice(
    invoiceNumber: '982347',
    products: products,
    customerName: 'Abraham Swearegin',
    customerAddress: '54 rue de Rivoli\n75001 Paris, France',
    paymentInfo:
        '4509 Wiseman Street\nKnoxville, Tennessee(TN), 37929\n865-372-0425',
    tax: .15,
    baseColor: PdfColors.teal,
    accentColor: PdfColors.blueGrey900,
  );

  return await invoice.buildPdf(pageFormat);
}

class Invoice {
  Invoice({
    this.products,
    this.customerName,
    this.customerAddress,
    this.invoiceNumber,
    this.tax,
    this.paymentInfo,
    this.baseColor,
    this.accentColor,
  });

  final List<Product> products;
  final String customerName;
  final String customerAddress;
  final String invoiceNumber;


  static const _darkColor = PdfColors.blueGrey800;
  static const _lightColor = PdfColors.white;

  PdfColor get _baseTextColor =>
      baseColor.luminance < 0.5 ? _lightColor : _darkColor;

  PdfColor get _accentTextColor =>
      baseColor.luminance < 0.5 ? _lightColor : _darkColor;

  double get _total =>
      products.map<double>((p) => p.total).reduce((a, b) => a + b);

  double get _grandTotal => _total * (1 + tax);

  PdfImage _logo;

  Future<Uint8List> buildPdf(PdfPageFormat pageFormat) async {
    // Create a PDF document.
    final doc = pw.Document();

    final font1 = await rootBundle.load('assets/roboto1.ttf');
    final font2 = await rootBundle.load('assets/roboto2.ttf');
    final font3 = await rootBundle.load('assets/roboto3.ttf');

    _logo = PdfImage.file(
      doc.document,
      bytes: (await rootBundle.load('assets/logo.png')).buffer.asUint8List(),
    );

    // Add page to the PDF
    doc.addPage(
      pw.MultiPage(
        pageTheme: _buildTheme(
          pageFormat,
          font1 != null ? pw.Font.ttf(font1) : null,
          font2 != null ? pw.Font.ttf(font2) : null,
          font3 != null ? pw.Font.ttf(font3) : null,
        ),
        header: _buildHeader,
        footer: _buildFooter,
        build: (context) => [
          _contentHeader(context),
          _contentTable(context),
          pw.SizedBox(height: 20),
          _contentFooter(context),
          pw.SizedBox(height: 20),
          _termsAndConditions(context),
        ],
      ),
    );

    // Return the PDF file content
    return doc.save();
  }

BEARBEITEN :: Ich versuche dies jetzt zu tun, aber ich bekomme eine rote Unterstreichung unter der kommentierten Zeile

   class MyWidget extends StatelessWidget {
  @override
  Widget build(context) {
    return FutureBuilder<Uint8List>(
        future:  generateInvoice(PdfPageFormat.a4),
        builder: (context, AsyncSnapshot<Uint8List> snapshot) {
          if (snapshot.hasData) {
            return snapshot.data;  //get a red underline here
          } else {
            return CircularProgressIndicator();
          }
        }
    );
  }
}

Antworten

1 TipuSultan Aug 18 2020 at 10:41

Ihre Arbeitsfunktion sollte so aussehen. Hier habe ich zwei zusätzliche Pakete verwendet. Zum Anzeigen von pdf flutter_pdfview und zum Speichern des temporären pdf path_providers .

Future<Widget> work() async{
       Uint8List pdf = await generateInvoice(PdfPageFormat.a4);
       File file = await getPdf(pdf);
       return PDFView(
          filePath: file.path,
          autoSpacing: false,
          pageFling: false,
        );
     }

EDITIERT:

Future<File> getPdf(Uint8List pdf) async{
    Directory output = await getTemporaryDirectory();
    file = File(output.path+"/name_of_the_pdf.pdf");
    await file.writeAsBytes(pdf);
    return file;
  }

Aktualisieren Sie nun Ihre Erstellungsmethode als

@override
  Widget build(context) {
    return FutureBuilder<Widget>(
        future:  work(),
        builder: (BuildContext context, AsyncSnapshot<Widget> snapshot) {
          if (snapshot.hasData) {
            return snapshot.data;  //get a red underline here
          } else {
            return CircularProgressIndicator();
          }
        }
    );
  }