EdsonBueno / infinite_scroll_pagination

Flutter package to help you lazily load and display pages of items as the user scrolls down your screen.
https://pub.dev/packages/infinite_scroll_pagination
MIT License
634 stars 215 forks source link

Error when refreshing page with _pagingController.refresh() #144

Closed HaardikBhagtani closed 2 years ago

HaardikBhagtani commented 3 years ago

When refreshing using _pagingController.refresh(), getting this error and black screen

Code

import 'dart:convert';
import 'package:balaloka/constants/api_links.dart';
import 'package:balaloka/modals/video_details.dart';
import 'package:balaloka/widgets/video_card.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';

class CommonVideoListing extends StatefulWidget {
  final int favouriteVideos;
  final int userId;
  CommonVideoListing({required this.userId, required this.favouriteVideos});
  @override
  _CommonVideoListingState createState() => _CommonVideoListingState();
}

class _CommonVideoListingState extends State<CommonVideoListing> {
  late Video video;
  final PagingController<int, Video> _pagingController = PagingController(
    firstPageKey: 0,
    invisibleItemsThreshold: 1,
  );
  static const _pageSize = 10;
  int pageNumber = 1;
  int videosReceived = 0;

  @override
  void dispose() {
    _pagingController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    _pagingController.addPageRequestListener((pageKey) {
      print('controller pageKey $pageKey');

      print(_pagingController.value.status);
      // if () {}
      listingDataAPI(pageKey);
    });

  }

  Future<void> listingDataAPI(int pageKey) async {
    if (widget.userId == -100) {
      print('enter');
      print(pageNumber);
      final SharedPreferences sharedPreferences =
          await SharedPreferences.getInstance();
      var parentId = sharedPreferences.getString('parentId');

      try {
        http.Response response = await http.get(Uri.parse(API.videoListingsAPI +
            'UserId=$parentId&queryText=&onlyfavouritevideos=${widget.favouriteVideos}&pagenumber=$pageNumber&pagesize=$_pageSize'));
        var parsed = jsonDecode(response.body);
        print(parsed);
        print('parsed');
        if (parsed != null) {
          video = Video.fromJson(parsed);
          print(video.videoDetails.length);

          final newItems = [video];
          final isLastPage = newItems[0].videoDetails.length < _pageSize;
          print(isLastPage);
          videosReceived += newItems[0].videoDetails.length;
          if (isLastPage ||
              newItems[0].videoDetails[0].totalVideos == videosReceived) {
            _pagingController.appendLastPage(newItems);
          } else {
            final nextPageKey = pageKey + newItems[0].videoDetails.length;
            _pagingController.appendPage(newItems, nextPageKey);
          }
          setState(() {
            pageNumber += 1;
          });
        } else {
          _pagingController.appendPage([], 1);
        }
      } catch (error) {
        _pagingController.error = error;
      }
    } else {
      print('enter');
      print(pageNumber);
      try {
        http.Response response = await http.get(Uri.parse(API.videoListingsAPI +
            'UserId=${widget.userId}&queryText=&onlyfavouritevideos=${widget.favouriteVideos}&pagenumber=$pageNumber&pagesize=$_pageSize'));
        var parsed = jsonDecode(response.body);
        print(parsed);
        if (parsed != null) {
          video = Video.fromJson(parsed);
          print(video.videoDetails.length);

          final newItems = [video];
          final isLastPage = newItems[0].videoDetails.length < _pageSize;
          print(isLastPage);
          videosReceived += newItems[0].videoDetails.length;
          if (isLastPage ||
              newItems[0].videoDetails[0].totalVideos == videosReceived) {
            _pagingController.appendLastPage(newItems);
          } else {
            final nextPageKey = pageKey + newItems[0].videoDetails.length;
            _pagingController.appendPage(newItems, nextPageKey);
          }
          setState(() {
            pageNumber += 1;
          });
        } else {
          _pagingController.appendPage([], 1);
        }
      } catch (error) {
        _pagingController.error = error;
      }

    }
  }

  @override
  Widget build(BuildContext context) {
    final MediaQueryData queryData = MediaQuery.of(context);
    // final height = queryData.size.height;
    final width = queryData.size.width;
    return Padding(
        padding: EdgeInsets.only(
          left: 0.05 * width,
          right: 0.05 * width,
        ),
        child: RefreshIndicator(
          onRefresh: () => Future.sync(
            () => _pagingController.refresh(),
          ),
          child: CustomScrollView(
            slivers: [
              PagedSliverList<int, Video>(
                pagingController: _pagingController,
                builderDelegate: PagedChildBuilderDelegate<Video>(
                  itemBuilder: (context, item, i) {
                    print('indexing');
                    print(_pagingController.value.status);
                    return ListView.builder(
                      controller: ScrollController(),
                      shrinkWrap: true,
                      itemCount: item.videoDetails.length,
                      itemBuilder: (BuildContext context, int index) {
                        return VideoCard(
                          video: item,
                          context: context,
                          index: index,
                          userId: widget.userId,
                          videoId: -100,
                        );
                      },
                    );
                  },
                  noItemsFoundIndicatorBuilder: (context) {
                    return Center(child: Text('No Videos Found'));
                  },
                  noMoreItemsIndicatorBuilder: (context) {
                    return Text('No More Videos Found');
                  },
                  newPageProgressIndicatorBuilder: (context) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  },
                  firstPageProgressIndicatorBuilder: (context) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  },
                ),
              ),
            ],
          ),
        )
        );
  }
}

Error

======== Exception caught by scheduler library =====================================================
The following assertion was thrown during a scheduler callback:
'package:flutter/src/rendering/viewport.dart': Failed assertion: line 1702 pos 12: 'center!.parent == this': is not true.

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

When the exception was thrown, this was the stack: 
#2      RenderViewport.indexOfFirstChild (package:flutter/src/rendering/viewport.dart:1702:12)
#3      RenderViewportBase.debugDescribeChildren (package:flutter/src/rendering/viewport.dart:974:17)
#4      DiagnosticableTreeNode.getChildren (package:flutter/src/foundation/diagnostics.dart:2995:48)
#5      DiagnosticsNode.toJsonMap.<anonymous closure> (package:flutter/src/foundation/diagnostics.dart:1567:32)
#6      DiagnosticsNode.toJsonMap (package:flutter/src/foundation/diagnostics.dart:1608:6)
#7      DiagnosticsNode.toJsonList.<anonymous closure> (package:flutter/src/foundation/diagnostics.dart:1632:19)
#8      MappedListIterable.elementAt (dart:_internal/iterable.dart:413:31)
#9      ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
#10     new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
#11     new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
#12     new List.of (dart:core-patch/array_patch.dart:50:28)
#13     ListIterable.toList (dart:_internal/iterable.dart:213:44)
#14     DiagnosticsNode.toJsonList (package:flutter/src/foundation/diagnostics.dart:1633:8)
#15     DiagnosticsNode.toJsonMap.<anonymous closure> (package:flutter/src/foundation/diagnostics.dart:1595:25)
#16     DiagnosticsNode.toJsonMap (package:flutter/src/foundation/diagnostics.dart:1608:6)
#17     WidgetInspectorService._nodeToJson (package:flutter/src/widgets/widget_inspector.dart:1518:18)
#18     WidgetInspectorService._reportError (package:flutter/src/widgets/widget_inspector.dart:924:44)
#19     FlutterError.reportError (package:flutter/src/foundation/assertions.dart:1131:14)
#20     RenderObject._debugReportException (package:flutter/src/rendering/object.dart:1373:18)
#21     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1716:7)
#22     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:885:18)
#23     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:453:19)
#24     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:883:13)
#25     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:319:5)
#26     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15)
#27     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9)
#28     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#32     _invoke (dart:ui/hooks.dart:166:10)
#33     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#34     _drawFrame (dart:ui/hooks.dart:129:31)
(elided 5 frames from class _AssertionError and dart:async)
====================================================================================================

======== Exception caught by scheduler library =====================================================
The following assertion was thrown during a scheduler callback:
RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout().
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1937 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout ||
              (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

When the exception was thrown, this was the stack: 
#2      RenderBox.size.<anonymous closure> (package:flutter/src/rendering/box.dart:1937:13)
#3      RenderBox.size (package:flutter/src/rendering/box.dart:1950:6)
#4      RenderBox.paintBounds (package:flutter/src/rendering/box.dart:2567:41)
#5      PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:140:56)
#6      PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:100:5)
#7      PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:979:29)
#8      RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:455:19)
#9      WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:883:13)
#10     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:319:5)
#11     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15)
#12     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9)
#13     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#17     _invoke (dart:ui/hooks.dart:166:10)
#18     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#19     _drawFrame (dart:ui/hooks.dart:129:31)
(elided 5 frames from class _AssertionError and dart:async)
====================================================================================================
EdsonBueno commented 2 years ago

Why are you using a ListView inside a PagedSliverList and a CustomScrollView? That's why it doesn't work. Try re-structuring your UI. I'm closing the issue for now, but feel free to continue the discussion.

HaardikBhagtani commented 2 years ago

@EdsonBueno ListView.builder is creating 10 VideoCard as u can see. Each item of PagingController is having 10 VideoCards. What is a alternative to this??

EdsonBueno commented 2 years ago

Try using a Column.

HaardikBhagtani commented 2 years ago

How can I use Column ? Api can send atmost 10 VideoCard details each time, according to data available in backend. So, how to build VideoCard in Column upon I get data from api??