inview_notifier_list icon indicating copy to clipboard operation
inview_notifier_list copied to clipboard

Expose InViewNotifier to support customized widget #47

Open dreamer2q opened this issue 3 years ago • 5 comments
trafficstars

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

  • Expose InViewNotifier and change ScrollView to Widget to support customized widget
  • Add RefreshList with SmartRefresh example to demo refreshing and loading

dreamer2q avatar Mar 11 '22 08:03 dreamer2q

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.

inc16sec avatar Apr 04 '22 23:04 inc16sec

@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.

dreamer2q avatar Apr 05 '22 03:04 dreamer2q

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.

inc16sec avatar Apr 05 '22 17:04 inc16sec

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

dreamer2q avatar Apr 05 '22 17:04 dreamer2q

@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.

inc16sec avatar Apr 05 '22 17:04 inc16sec