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
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];
});
},
);
}