首页 > 解决方案 > Flutter 错误 - 用于空值的空检查运算符(PDF 查看器)

问题描述

你好,我是 Flutter 的新手。当我计算这个操作时,我的代码中出现了这个错误。我已经在我的 pubspec.yaml 文件中导入了所有依赖项。请帮我。

错误

用于空值的空检查运算符

文件视图.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:offlinefileviewer/pdfapi.dart';
import 'package:offlinefileviewer/pdfviewerpage.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("File viewer"),
      ),
      body: ElevatedButton(
        onPressed: () async {
          final path = 'assets/pdf1.pdf';
          final file = await PdfApi.loadAsset(path);
          openPDF(context, file);
        },
        child: Text("Asset File"),
      ),
    );
  }

  void openPDF(BuildContext context, File file) => 
        Navigator.of(context).push(
        MaterialPageRoute(builder: (_) => PDFViewerPage(key: key!, file: file)),
      );
}

pdfviewerpage.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:path/path.dart';

class PDFViewerPage extends StatefulWidget {
  final File? file;

  const PDFViewerPage({
    Key? key,
    this.file,
  }) : super(key: key);

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

class _PDFViewerPageState extends State<PDFViewerPage> {
  PDFViewController? controller;
  int? pages;
  int? indexPage;

  @override
  Widget build(BuildContext context) {
    final name = basename(widget.file!.path);
    final text = '${indexPage! + 1} of $pages';

    return Scaffold(
      appBar: AppBar(
        title: Text(name),
        actions: pages! >= 2
            ? [
                Center(child: Text(text)),
                IconButton(
                  icon: Icon(Icons.chevron_left, size: 32),
                  onPressed: () {
                    final page = indexPage == 0 ? pages : indexPage! - 1;
                    controller!.setPage(page!);
                  },
                ),
                IconButton(
                  icon: Icon(Icons.chevron_right, size: 32),
                  onPressed: () {
                    final page = indexPage == pages! - 1 ? 0 : indexPage! + 1;
                    controller!.setPage(page);
                  },
                ),
              ]
            : null,
      ),
      body: PDFView(
        filePath: widget.file!.path,
        onRender: (pages) => setState(() => this.pages = pages!),
        onViewCreated: (controller) =>
            setState(() => this.controller = controller),
        onPageChanged: (indexPage, _) =>
            setState(() => this.indexPage = indexPage!),
      ),
    );
  }
}

错误

════════ 小部件库捕获的异常═════════════════════════════␕══以下_CastError 被抛出构建 Builder(dirty): Null check operator used on a null value

The relevant error-causing widget was
MaterialApp
lib\main.dart:12
When the exception was thrown, this was the stack
#0      FileView.openPDF.<anonymous closure>
package:offlinefileviewer/fileview.dart:28
#1      MaterialPageRoute.buildContent
package:flutter/…/material/page.dart:53
#2      MaterialRouteTransitionMixin.buildPage
package:flutter/…/material/page.dart:106
#3      _ModalScopeState.build.<anonymous closure>.<anonymous closure>
package:flutter/…/widgets/routes.dart:843
#4      Builder.build
package:flutter/…/widgets/basic.dart:7798
...
════════════════════════════════════════════════════════════════════════════════

标签: flutterdartpdf-viewer

解决方案


尽可能避免使用可为空的变量。这样分析仪本身就安全且可预测。

  1. !尽可能避免使用运算符。看到这个

但是,您应该能够使用if条件包装对可空变量的每次访问,以避免在它为空时继续。使用!时,强烈建议使用某种检查(最好使用if条件来查看值是否为空,否则执行当值为空时应该做的事情)

class PDFViewerPage extends StatefulWidget {
  final File file;

  const PDFViewerPage({
    Key? key,
    required this.file,
  }) : super(key: key);

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

class _PDFViewerPageState extends State<PDFViewerPage> {
  PDFViewController? controller;
  int? pages;
  int? indexPage;

  late final String name;
  String get text => '${indexPage ?? 0 + 1} of ${pages ?? 0}';

  @override
  void initState() {
    name = basename(widget.file.path);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(name),
        actions: (pages ?? 0) >= 2 // edited
            ? [
                Center(child: Text(text)),
                IconButton(
                  icon: Icon(Icons.chevron_left, size: 32),
                  onPressed: () {
                    if (controller == null || pages == null) {
                      return;
                    }

                    final page =
                        (indexPage ?? 0) == 0 ? pages! : indexPage! - 1;

                    controller!.setPage(page);
                  },
                ),
                IconButton(
                  icon: Icon(Icons.chevron_right, size: 32),
                  onPressed: () {
                    if (controller == null || pages == null) {
                      return;
                    }

                    final page = (indexPage ?? 0) == pages! - 1
                        ? 0
                        : (indexPage ?? 0) + 1;

                    controller?.setPage(page);
                  },
                ),
              ]
            : null,
      ),
      body: PDFView(
        filePath: widget.file.path,
        onRender: (pages) => setState(() => this.pages = pages!),
        onViewCreated: (controller) =>
            setState(() => this.controller = controller),
        onPageChanged: (indexPage, _) =>
            setState(() => this.indexPage = indexPage!),
      ),
    );
  }
}
  1. 在您fileview.dart的方法openPdf中,key可能为空。在运行时,它恰好是一个空值,并且!使用了运算符,导致它抛出该异常。

只需删除!运算符,也可以解决问题,因为它也PDFViewerPage接受可为空的key参数。

这可能会有所帮助:

  void openPDF(BuildContext context, File file) => 
        Navigator.of(context).push(
        MaterialPageRoute(builder: (_) => PDFViewerPage(key: key, file: file)),
      );

推荐阅读