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

"Unexpected null value." when running against Channel beta, 1.23.0-18.1.pre #18

Closed
alexagat opened this issue Oct 26, 2020 · 8 comments
Closed

Comments

@alexagat
Copy link

After upgrading the Flutter beta channel to latest:
[✓] Flutter (Channel beta, 1.23.0-18.1.pre, on Mac OS X 10.15.7 19H2 x86_64, locale en-US)

I get the following output in the console and an error in place of the PreloadPageView widget:

════════ Exception caught by widgets library ═══════════════════════════════════
The following TypeErrorImpl was thrown building NotificationListener<ScrollNotification>:
Unexpected null value.

The relevant error-causing widget was
NotificationListener<ScrollNotification>
../…/lib/preload_page_view.dart:572
When the exception was thrown, this was the stack
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 216:49      throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 518:63  nullCheck
packages/flutter/src/widgets/scroll_position.dart 166:31                          get pixels
packages/preload_page_view/preload_page_view.dart 269:16                          restoreScrollOffset
packages/flutter/src/widgets/scroll_position.dart 106:7                           new
...
════════════════════════════════════════════════════════════════════════════════

Any help or guidance is appreciated. I created a new project with only the example code to ensure it was not a conflict with my app-specific implementation.

@savs90
Copy link

savs90 commented Oct 30, 2020

This is related to the new dart version that flutter is using. They introduced null safety and as I can see updated the framework to the last syntax. I played a bit until make a fix.
Just exchange _PagePosition class with the code under:

class _PagePosition extends ScrollPositionWithSingleContext implements PageMetrics {
  _PagePosition({
    ScrollPhysics physics,
    ScrollContext context,
    this.initialPage = 0,
    bool keepPage = true,
    double viewportFraction = 1.0,
    ScrollPosition oldPosition,
  })  : assert(initialPage != null),
        assert(keepPage != null),
        assert(viewportFraction != null),
        assert(viewportFraction > 0.0),
        _viewportFraction = viewportFraction,
        _pageToUseOnStartup = initialPage.toDouble(),
        super(
          physics: physics,
          context: context,
          initialPixels: null,
          keepScrollOffset: keepPage,
          oldPosition: oldPosition,
        );

  final int initialPage;
  double _pageToUseOnStartup;

  @override
  double get viewportFraction => _viewportFraction;
  double _viewportFraction;

  set viewportFraction(double value) {
    if (_viewportFraction == value) return;
    final double oldPage = page;
    _viewportFraction = value;
    if (oldPage != null) forcePixels(getPixelsFromPage(oldPage));
  }

  double getPageFromPixels(double pixels, double viewportDimension) {
    return math.max(0.0, pixels) / math.max(1.0, viewportDimension * viewportFraction);
  }

  double getPixelsFromPage(double page) {
    return page * ((hasViewportDimension == true) ? viewportDimension : 0) * viewportFraction;
  }

  @override
  double get page => (hasPixels == false)
      ? null
      : getPageFromPixels(
          pixels.clamp((hasContentDimensions == true) ? minScrollExtent : null, (hasContentDimensions == true) ? maxScrollExtent : null),
          (hasViewportDimension == true) ? viewportDimension : null,
        );

  @override
  void saveScrollOffset() {
    PageStorage.of(context.storageContext)
        ?.writeState(context.storageContext, getPageFromPixels((hasPixels) ? pixels : null, (hasViewportDimension) ? viewportDimension : null));
  }

  @override
  void restoreScrollOffset() {
    if (hasPixels == true) {
      final double value = PageStorage.of(context.storageContext)?.readState(context.storageContext);
      if (value != null) _pageToUseOnStartup = value;
    }
  }

  @override
  bool applyViewportDimension(double viewportDimension) {
    final double oldViewportDimensions = (hasViewportDimension) ? this.viewportDimension : null;
    final bool result = super.applyViewportDimension(viewportDimension);
    final double oldPixels = (hasPixels) ? pixels : null;
    final double page = (oldPixels == null || oldViewportDimensions == 0.0) ? _pageToUseOnStartup : getPageFromPixels(oldPixels, oldViewportDimensions);
    final double newPixels = getPixelsFromPage(page);
    if (newPixels != oldPixels) {
      correctPixels(newPixels);
      return false;
    }
    return result;
  }

  @override
  PageMetrics copyWith({
    double minScrollExtent,
    double maxScrollExtent,
    double pixels,
    double viewportDimension,
    AxisDirection axisDirection,
    double viewportFraction,
  }) {
    return PageMetrics(
      minScrollExtent: minScrollExtent ?? ((hasContentDimensions) ? this.minScrollExtent : null),
      maxScrollExtent: maxScrollExtent ?? ((hasContentDimensions) ? this.maxScrollExtent : null),
      pixels: pixels ?? ((hasPixels) ? this.pixels : null),
      viewportDimension: viewportDimension ?? ((hasViewportDimension) ? this.viewportDimension : null),
      axisDirection: axisDirection ?? this.axisDirection,
      viewportFraction: viewportFraction ?? this.viewportFraction,
    );
  }
}

This should take in consideration the new syntax. Please test and give a review so other people with the same problem could fix it.

@alexagat
Copy link
Author

alexagat commented Nov 3, 2020

@savs90 this is working for Channel beta, 1.23.0-18.1.pre. Please consider adding this change in.

@crtl
Copy link

crtl commented Nov 6, 2020

@savs90 Thanks your saving my day. Working on master.
I have created a fork and applied your chages their it is avalable with:

preload_page_view:
    git:
      url: "https://github.com/crtl/preload_page_view.git"
      ref: "fix-null-check-operators"

@Bonsai11
Copy link

Bonsai11 commented Jan 6, 2021

And once again we see the downsides of plugins.
There shouldn't be a fork that fixes this. It should be fixed here and updated on pub.dev.
@octomato @wrbl606

In a perfect world, this would be added in the actual flutter widget, so nobody needs a plugin for this.

@octomato octomato added the Fixing On the way to fix this issue label Jan 7, 2021
@octomato
Copy link
Owner

octomato commented Jan 7, 2021

@Bonsai11 Thanks for the reminder, will review the code and create a PR later on

@octomato
Copy link
Owner

octomato commented Jan 7, 2021

@Bonsai11 @savs90 @crtl Please review the PR #21

@octomato octomato added Ready for review and removed Fixing On the way to fix this issue labels Jan 7, 2021
@octomato
Copy link
Owner

Fixed it.

@Bonsai11
Copy link

Thanks, thats very good, do you have any plans yet to update this on pub.dev?

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

No branches or pull requests

5 participants