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

Get uncaught null check error when trying to modify widget tree #46

Closed
pckimlong opened this issue Jan 24, 2024 · 4 comments
Closed

Get uncaught null check error when trying to modify widget tree #46

pckimlong opened this issue Jan 24, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@pckimlong
Copy link

As an example

class Example extends StatefulWidget {
  const Example({super.key, required this.path});

  final String path;

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  final controller = PdfViewerController();
  bool darkMode = false;

  @override
  Widget build(BuildContext context) {
    Widget pdfWidget = PdfViewer.file(widget.path, controller: controller);

    if (darkMode) {
      pdfWidget = ColorFiltered(
        colorFilter: const ColorFilter.mode(Colors.white, BlendMode.difference),
        child: pdfWidget,
      );
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text('TEST'),
        actions: [
          IconButton(
            onPressed: () => setState(() => darkMode = !darkMode),
            icon: const Icon(Icons.dark_mode),
          ),
        ],
      ),
      body: pdfWidget,
    );
  }
}

This is the error:
E/flutter (30841): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value E/flutter (30841): #0 PdfViewerController.goToPage (package:pdfrx/src/widgets/pdf_viewer.dart:1020:19) E/flutter (30841): #1 _PdfViewerState.build.<anonymous closure>.<anonymous closure> (package:pdfrx/src/widgets/pdf_viewer.dart:372:26) E/flutter (30841): #2 new Future.microtask.<anonymous closure> (dart:async/future.dart:280:37) E/flutter (30841): #3 _microtaskLoop (dart:async/schedule_microtask.dart:40:21) E/flutter (30841): #4 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5) E/flutter (30841): I/flutter (30841): ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── I/flutter (30841): │ Null check operator used on a null value I/flutter (30841): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ I/flutter (30841): │ 08:18:00.958 (+0:00:21.649522) I/flutter (30841): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ I/flutter (30841): │ ⛔ Uncaught flutter error I/flutter (30841): └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── I/flutter (30841): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter (30841): The following _TypeError was thrown during paint(): I/flutter (30841): Null check operator used on a null value I/flutter (30841): I/flutter (30841): The relevant error-causing widget was: I/flutter (30841): PdfViewer I/flutter (30841): PdfViewer:file:///Users/kim/Development/projects/freelance/books_5000/lib/src/presentation/modules/book/viewer/book_viewer_page.dart:116:34 I/flutter (30841): I/flutter (30841): When the exception was thrown, this was the stack: I/flutter (30841): #0 PdfViewerController.viewSize (package:pdfrx/src/widgets/pdf_viewer.dart:874:30) I/flutter (30841): #1 PdfViewerController.visibleRect (package:pdfrx/src/widgets/pdf_viewer.dart:887:49) I/flutter (30841): #2 _PdfViewerState._getCacheExtentRect (package:pdfrx/src/widgets/pdf_viewer.dart:666:38) I/flutter (30841): #3 _PdfViewerState._customPaint (package:pdfrx/src/widgets/pdf_viewer.dart:707:24) I/flutter (30841): #4 _CustomPainter.paint (package:pdfrx/src/widgets/pdf_viewer.dart:1296:62) I/flutter (30841): #5 RenderCustomPaint._paintWithPainter (package:flutter/src/rendering/custom_paint.dart:588:13) I/flutter (30841): #6 RenderCustomPaint.paint (package:flutter/src/rendering/custom_paint.dart:635:7) I/flutter (30841): #7 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #8 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #9 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129:13) I/flutter (30841): #10 PaintingContext.pushTransform (package:flutter/src/rendering/object.dart:687:14) I/flutter (30841): #11 RenderTransform.paint (package:flutter/src/rendering/proxy_box.dart:2529:27) I/flutter (30841): #12 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #13 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #14 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:74:15) I/flutter (30841): #15 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #16 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #17 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129:13) I/flutter (30841): #18 PaintingContext.pushClipRect.<anonymous closure> (package:flutter/src/rendering/object.dart:549:83) I/flutter (30841): #19 ClipContext._clipAndPaint (package:flutter/src/painting/clip.dart:25:12) I/flutter (30841): #20 ClipContext.clipRectAndPaint (package:flutter/src/painting/clip.dart:53:5) I/flutter (30841): #21 PaintingContext.pushClipRect (package:flutter/src/rendering/object.dart:549:7) I/flutter (30841): #22 RenderClipRect.paint (package:flutter/src/rendering/proxy_box.dart:1532:25) I/flutter (30841): #23 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #24 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #25 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129:13) I/flutter (30841): #26 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #27 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #28 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129:13) I/flutter (30841): #29 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #30 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #31 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129:13) I/flutter (30841): #32 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #33 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #34 RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2882:15) I/flutter (30841): #35 RenderStack.paintStack (package:flutter/src/rendering/stack.dart:640:5) I/flutter (30841): #36 RenderStack.paint (package:flutter/src/rendering/stack.dart:656:7) I/flutter (30841): #37 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #38 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #39 RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:129:13) I/flutter (30841): #40 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #41 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #42 _RenderColoredBox.paint (package:flutter/src/widgets/basic.dart:7813:15) I/flutter (30841): #43 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #44 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13) I/flutter (30841): #45 _RenderLayoutBuilder.paint (package:flutter/src/widgets/layout_builder.dart:333:15) I/flutter (30841): #46 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:3208:7) I/flutter (30841): #47 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:250:13)

Noted that this error occurred only when using controller, If I don't apply controller, it'll worked just fine

@espresso3389 espresso3389 added the bug Something isn't working label Jan 25, 2024
@espresso3389
Copy link
Owner

How about to change the way ColorFiltered is toggled:

class _ExampleState extends State<Example> {
  final controller = PdfViewerController();
  bool darkMode = false;

  @override
  Widget build(BuildContext context) {
    final pdfWidget = ColorFiltered(
      colorFilter: ColorFilter.mode(
          Colors.white, darkMode ? BlendMode.difference : BlendMode.dst),
      child: PdfViewer.file(widget.path, controller: controller),
    );

    return Scaffold(
      appBar: AppBar(
        title: const Text('TEST'),
        actions: [
          IconButton(
            onPressed: () => setState(() => darkMode = !darkMode),
            icon: const Icon(Icons.dark_mode),
          ),
        ],
      ),
      body: pdfWidget,
    );
  }
}

@espresso3389
Copy link
Owner

espresso3389 commented Jan 25, 2024

Basically, this is the issue with PdfViewer itself (controller does not wait for widget recreated) but if you keep the parent structure, or keep the PdfViewer widget by some other mechanism such as GlobalKey, the problem is gone.

@espresso3389
Copy link
Owner

Other change proposals from GitHub Copilot (I'm not tested yet):

class _ExampleState extends State<Example> {
  final controller = PdfViewerController();
  bool darkMode = false;
  late final Widget pdfWidget;

  @override
  void initState() {
    super.initState();
    pdfWidget = PdfViewer.uri(widget.uri, controller: controller);
  }

  @override
  Widget build(BuildContext context) {
    Widget currentWidget = pdfWidget;

    if (darkMode) {
      currentWidget = ColorFiltered(
        colorFilter: const ColorFilter.mode(Colors.white, BlendMode.difference),
        child: currentWidget,
      );
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text('TEST'),
        actions: [
          IconButton(
            onPressed: () => setState(() => darkMode = !darkMode),
            icon: const Icon(Icons.dark_mode),
          ),
        ],
      ),
      body: currentWidget,
    );
  }
}
class _ExampleState extends State<Example> {
  final controller = PdfViewerController();
  final ValueNotifier<bool> darkMode = ValueNotifier(false);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('TEST'),
        actions: [
          IconButton(
            onPressed: () => darkMode.value = !darkMode.value,
            icon: const Icon(Icons.dark_mode),
          ),
        ],
      ),
      body: ValueListenableBuilder<bool>(
        valueListenable: darkMode,
        builder: (context, darkModeValue, child) {
          return darkModeValue
              ? ColorFiltered(
                  colorFilter: const ColorFilter.mode(
                      Colors.white, BlendMode.difference),
                  child: child,
                )
              : child!;
        },
        child: PdfViewer.uri(widget.uri, controller: controller),
      ),
    );
  }
}

@espresso3389
Copy link
Owner

@pckimlong
On 1227b0f, I've added note about dark/night mode support on README.md; that is based on your code. Thanks so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants