0

I'm developing an app with an infinite scroll. My scroll is returned inside futurebuilder.

  @override
  Widget build(BuildContext context) {
  return FutureBuilder(
  future: VideoService.getFeed(page: page),
  builder: (context, AsyncSnapshot snapshot) {
   if (snapshot.hasData) {
      /*print(snapshot.data);
      print(page.toString());*/

     _tabController = TabController(
          length: (snapshot.data.length + items.length), vsync: this);
      _tabController.addListener(_tabControllerListener);

      items.addAll(snapshot.data);
      items.removeWhere((element) => (element == null));

      return getBody();
    }

    return Center(child: CircularProgressIndicator());
  },
);}

I use tabcontroller to decide when to call my API:

_tabControllerListener() {
if ((_tabController.length - 1) == _tabController.index) {
  /*_tabController.index = _tabController.index;*/

  
  setState(() {
   // _tabController = _tabController;
    page = page + 1;
    _tabController = _tabController;
    //items = items;

  });
} }

However the build function is called multiple times. How do I avoid this?

1 Answers1

0

You are creating a side effect when building the UI, and that is not desired. The build method should always return a widget and it shouldn't matter how many times is called. To avoid the future getting called, you need to save it in your state and "trigger" it inside the initState.

late Future<Feed> getFeedFuture;

void initState() {
  super.initState();
  getFeedFuture = VideoService.getFeed(page: 0);

  ...
}

_tabControllerListener() {
  setState(() {
    page = page + 1;
    getFeedFuture = VideoService.getFeed(page: page);
  });
}

...

FutureBuilder(
  future: getFeedFuture,
  ...
Martyns
  • 3,605
  • 22
  • 33