Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
584 views
in Technique[技术] by (71.8m points)

Flutter lazy loading from Api

I have problem with lazy loading. I tried may ways and packages like LazyLoadingScollview (example here), Pagewise etc. What the problem is (probably easy to solve).

I have list of 50 events and I want to display only 10 of it at once, than add more (ex another 10) while reach the bottom of the list. (I cannot change limit from 50 to 10 and change it later because it's refreshing whole screen - need to fetch all at once).

To be more clear - need update count value dynamicly.

class DiscountTab extends DiscountsBaseTab {
  @override
  _DiscountTabState createState() => _DiscountTabState();
}

class _DiscountTabState extends DiscountsBaseTabState
    with SnackBarMixin, TitleDescriptionTextMixin {
  DiscountsBloc bloc;
  PermissionStatus permissionStatus;
  bool isError = false;

  @override
  void initState() {
    super.initState();
    bloc = DiscountsBloc(
        DiscountsState.notProcessing(activeTab: DiscountsTabs.discount));
    _onRefresh();
    bloc.errors.listen((error) {
      showSnackBarTextWithContext(context: context, text: error.message);
      if (error.message ==
          "Connection error, try again later")
        isError = true;
    });
  }

  void _onRefresh() => bloc.emitEvent(DiscountsListEventFetch(limit: 50)); //Here I'm fetching events



  @override
  Widget buildBody(BuildContext context) {
    return StreamBuilder<List<DiscountsModel>>(
        stream: bloc.dataField.stream,
        builder: (BuildContext context,
            AsyncSnapshot<List<DiscountsModel>> snapshot) {
          if (!snapshot.hasData) {
            return Container();
          }
          return RefreshIndicator(
              onRefresh: () {
                _onRefresh();
                isError = false;
                return Future.sync(() {
                  return;
                });
              },
              color: LegionColors.primaryRedHigh,
              child: buildView(context, snapshot.data));
        });
  }

  buildView(BuildContext context, List<DiscountsModel> list) {
    int count = 10;

    return LazyLoadScrollView(
      onEndOfPage: () => print('End of page'),
      child: ListView.builder(
          shrinkWrap: true,
          itemCount: count + 1,
          itemBuilder: (BuildContext context, int index) {
            if (index == list.length) {
              return Padding(
                padding: const EdgeInsets.all(10.0),
                child: Center(
                    child: SizedBox(
                        width: 20.0,
                        height: 20.0,
                        child: CircularProgressIndicator())),
              );
            }
            return DiscountsWidget(model: list[index]);
          }),
    );
  }
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When I'm using regular ScrollController everything works fine since this moment. I mean my print statement works when i reach bottom, hovewer i cannot use loop inside loadMore.

class DiscountTab extends DiscountsBaseTab {
  @override
  _DiscountTabState createState() => _DiscountTabState();
}

class _DiscountTabState extends DiscountsBaseTabState
    with SnackBarMixin, TitleDescriptionTextMixin {
  DiscountsBloc bloc;
  PermissionStatus permissionStatus;
  bool isError = false;

  int count = 10;
  ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    bloc = DiscountsBloc(
        DiscountsState.notProcessing(activeTab: DiscountsTabs.discount));
    _onRefresh();
    bloc.errors.listen((error) {
      showSnackBarTextWithContext(context: context, text: error.message);
      if (error.message ==
          "Connection error")
        isError = true;
    });
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        _loadMore();
      }
    });
  }

 _loadMore() {
    print('End of page');
    for (int i = count; i < count + 10; i++) {
      //here i should add items but:
      // 1. i have it fetched already (all 50)
      // 2. cannot use list.add here because it's undefined
    }
  }

  void _onRefresh() => bloc.emitEvent(DiscountsListEventFetch(limit: 50));

  @override
  Widget buildBody(BuildContext context) {
    return StreamBuilder<List<DiscountsModel>>(
        stream: bloc.dataField.stream,
        builder: (BuildContext context,
            AsyncSnapshot<List<DiscountsModel>> snapshot) {
          if (!snapshot.hasData) {
            return Container();
          }
          return RefreshIndicator(
              onRefresh: () {
                _onRefresh();
                isError = false;
                return Future.sync(() {
                  return;
                });
              },
              color: LegionColors.primaryRedHigh,
              child: buildView(context, snapshot.data));
        });
  }

  buildView(BuildContext context, List<DiscountsModel> list) {
    return ListView.builder(
        shrinkWrap: true,
        controller: _scrollController,
        itemCount: count,
        itemBuilder: (BuildContext context, int index) {
          // if (index == list.length) {
          //   return Padding(
          //     padding: const EdgeInsets.all(10.0),
          //     child: Center(
          //         child: SizedBox(
          //             width: 20.0,
          //             height: 20.0,
          //             child: CircularProgressIndicator())),
          //   );
          // }
          return DiscountsWidget(model: list[index]);
        });
  }

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...