I get the counter integer from the Navigator.of arguments and display it on the appBar. It works fine but I have a decrement button that should decrement the counter by 1 each time it is fired but the UI isn`t updating ever after setState is called.
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final routeArgs = ModalRoute.of(context).settings.arguments as Map<String, String>;
int count;
String title;
if(routeArgs == null){
count = 1;
title = 'Title';
}
else {
count = int.parse(routeArgs['count']);
title = routeArgs['title'];
}
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: (){
setState(() {
count -= 1; //calling setState to decrease count by 1
});
},
),
InkWell(
child: Container(
child: Text(title),
),
onTap: ()=>Navigator.of(context).pushNamed('/choice'),
),
Container(
child: Text(count.toString()), //This is not updating after setState called.
),
IconButton(
icon: Icon(Icons.arrow_forward_ios),
onPressed: () {},
),
],
),
),
drawer: Drawer(),
);
}
}
Solution 1: dlohani
I think the problem is you have declared int count
inside build method. That re initializes the count variable every time you call setState so its not working. Try moving it outside build method as follows
class _MyHomePageState extends State<MyHomePage> {
int count; //this is moved outside of build function
@override
Widget build(BuildContext context) {
final routeArgs = ModalRoute.of(context).settings.arguments as Map<String, String>;
String title;
if(routeArgs == null){
count = count?? 1;
title = 'Title';
}
else {
count = count?? int.parse(routeArgs['count']);
title = routeArgs['title'];
}
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: (){
setState(() {
count -= 1; //calling setState to decrease count by 1
});
},
),
InkWell(
child: Container(
child: Text(title),
),
onTap: ()=>Navigator.of(context).pushNamed('/choice'),
),
Container(
child: Text(count.toString()), //This is not updating after setState called.
),
IconButton(
icon: Icon(Icons.arrow_forward_ios),
onPressed: () {},
),
],
),
),
drawer: Drawer(),
);
}
}
Solution 2: Yudhishthir Singh
If you put state variables in the build functions then they are initialised every time the build function runs, which is pretty frequent. You should always define state variables outside the build method and inside the class, so that the build function's re-running doesn't affect the current value that the state variable holds.
Solution 3: Broding Camel
You must set your count variable with 0 value like below code:
int count = 0;
Solution 4: Crazy Lazy Cat
Try this
class _MyHomePageState extends State<MyHomePage> {
int count = 1;
String title = 'Title';
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(_initializeFromArgs);
super.initState();
}
void _initializeFromArgs(_) {
final routeArgs =
ModalRoute.of(context).settings.arguments as Map<String, String>;
if (routeArgs != null) {
count = int.parse(routeArgs['count']);
title = routeArgs['title'];
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
setState(() {
count -= 1;
});
},
),
InkWell(
child: Container(
child: Text(title),
),
onTap: () => Navigator.of(context).pushNamed('/choice'),
),
Container(
child: Text(count.toString()),
),
IconButton(
icon: Icon(Icons.arrow_forward_ios),
onPressed: () {},
),
],
),
),
drawer: Drawer(),
);
}
}