Search code examples
flutterflutter-futurebuilderflutter-state

how to call setState inside FutureBuilder<List<dynamic>>in flutter


I am trying to call setState inside a ListView.builder which itself is inside a FutureBuilder

class BidScreen extends StatefulWidget {
  const BidScreen({super.key});

  @override
  State<BidScreen> createState() => _BidScreenState();
}

class _BidScreenState extends State<BidScreen>
    with AutomaticKeepAliveClientMixin {
  Tab _selectedSegment = Tab._new;
  bool isTrucker = false;
  bool isShipper = false;
  bool loadingComplete = false;

  final PageController controller = PageController();

  @override
  void initState() {
    super.initState();
    getProfileTypeFromSharedPref();
  }

  @override
  bool get wantKeepAlive => true;

  void handleOnPressedForTrucker(int onPressed) {
    if (onPressed == 0) {
      setState(() {});
    } else if (onPressed == 1) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    if (loadingComplete) {
      return CupertinoPageScaffold(
        navigationBar: CupertinoNavigationBar(
          transitionBetweenRoutes: false,
          leading: null,
          middle: CupertinoSlidingSegmentedControl<Tab>(
            groupValue: _selectedSegment,
            onValueChanged: (Tab? value) {
              if (value != null) {
                setState(() {
                  _selectedSegment = value;
                  controller.animateToPage(
                    _selectedSegment.index,
                    duration: const Duration(milliseconds: 300),
                    curve: Curves.ease,
                  );
                });
              }
            },
            children: tab(),
          ),
        ),
        child: Center(child: pageView()),
      );
    } else {
      return const CircularProgressIndicator();
    }
  }

  pageView() {
    return PageView(
      controller: controller,
      children: isTrucker ? truckerPageView : shipperPageView,
      onPageChanged: (index) {
        setState(() {
          _selectedSegment = Tab.values[index];
        });
      },
    );
  }

  final List<Widget> truckerPageView = <Widget>[
    // New bids
    FutureBuilder<List<dynamic>>(
      future: BidRepository().bidsTrucker('new'),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return const Center(child: CircularProgressIndicator());
        }
        final trips = snapshot.data!;
        return ListView.builder(
          itemCount: trips.length,
          itemBuilder: ((context, index) {
            final trip = trips[index];
            return AcceptBidCard(
              fromLocation:
                  '${trip['from_address']['name']}, ${trip['from_address']['country']}',
              toLocation:
                  '${trip['to_address']['name']}, ${trip['to_address']['country']}',
              bidderName: trip['customer_name'],
              date: DateFormat('dd-MM-yyyy')
                  .format(DateTime.parse(trip['trip_date'])),
              tripId: trip['trip_id'],
              onPressed: (pressed) => setState(() => 'here is the problem'),
            );
          }),
        );
      },
    ),
  ];
}

onPressed is typedef ValueChanged<in T> = void Function(T value). so I was trying to update list on button pressed.

this is the error message: The instance member 'setState' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression


Solution

  • The problem was I already initialized the list final List<Widget> truckerPageView , so hence the error The instance member 'setState' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression

    Solution

    Instead of initializing return a function like this:

    List<Widget> truckerPageView() {
        return [widget1,widget2,]
     }
    

    And call your function here:

    pageView() {
        return PageView(
          controller: controller,
          children: isTrucker ? truckerPageView() : shipperPageView,
          onPageChanged: (index) {
            setState(() {
              _selectedSegment = Tab.values[index];
            });
          },
        );
      }