rvamsikrishna / inview_notifier_list

A Flutter package that builds a list view and notifies when the widgets are on screen.
MIT License
677 stars 104 forks source link

Expose InViewNotifier to support customized widget #47 #49

Open dreamer2q opened 2 years ago

dreamer2q commented 2 years ago

Seeing #47 that refresh and loading is a common use-case, I made this pr in hope to help solve this issue.

inc16sec commented 2 years ago

Hello @dreamer2q I've used your fork of this package and it works as expected, but I still face an issue when scrolling up so fast. The error is about the renderObject not being active, see below;

[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: Cannot get renderObject of inactive element.
In order for an element to have a valid renderObject, it must be active, which means it is part of the tree.
Instead, this element is in the _ElementLifecycle.inactive state.
If you called this method from a State object, consider guarding it with State.mounted.
The findRenderObject() method was called for the following element:

I think there's already a fix to this issue in this pull request #https://github.com/rvamsikrishna/inview_notifier_list/pull/45#issue-1030242235

I don't know if it was merged with the latest update or not. When I used it (before the update) it fixed the issue, but now when using your pull I faced the error again.

Thank you for your effort it's much appreciated and looking forward to hearing from you. Best regards.

dreamer2q commented 2 years ago

@inc16sec Yes, I am sure #45 is merge and should fix it. If you could provide a minimal code to reproduce the problem, I'd be glad to help.

inc16sec commented 2 years ago

The problem really doesn't require much code all you have to do is scroll up the listView fast.

ScrollController? scrollController;

@override
  void initState() {
    super.initState();
    scrollController = ScrollController();

  }

  void listScrollUp(){
    scrollController.animateTo(
      0.0, 
      duration: const Duration(milliseconds: 300), 
      curve: Curves.ease,
    );
  }

And call the listScrollUp() function from any button you have.

a listview would be something like

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          listScrollUp();
        },
      ),
      body: InViewNotifier(
        initialInViewIds: const ['0'],
        isInViewPortCondition: _checkTimelineItemIsInViewport,
        child: ListView.builder(
          controller: scrollController,
          itemCount: 500,
          itemBuilder: (c, i) => Container(
            height: 250,
            color: i % 2 == 0 ? Colors.red : Colors.green,
          ),
        ),
      )
    );
  }

  bool _checkTimelineItemIsInViewport(
    double deltaTop,
    double deltaBottom,
    double viewPortDimension,
  ) {
    return deltaTop < (0.5 * viewPortDimension) &&
        deltaBottom > (0.5 * viewPortDimension);
  }

Thank you for your response.

dreamer2q commented 2 years ago

@inc16sec Actually, I cannot reproduce such error using your code. Besides, your code seems missing InViewNotifierWidget.

inc16sec commented 2 years ago

@inc16sec Actually, I cannot reproduce such error using your code. Besides, your code seems missing InViewNotifierWidget.

My bad I forgot InViewNotifierWidget. I'll try to reproduce the error and share the code with you.