Flutter Switch - onChanged Not Changing
Solution 1
I added additional code chunks according to @Zulfiqar 's answer. I didn't test this code but I m using similar codes in my project. if you want to save it and use in another class or if you want to show latest state for everytime you load you can save the state in a global variable and call it when you load the class. hope it will help..
class Tab_b extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _TabsPageState();
}
class _TabsPageState extends State<Tab_b>{
bool isInstructionView;
@override
void initState() {
isInstructionView = Global.shared.isInstructionView;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("add data"),
),
body: new Container(
child: Switch(
value: isInstructionView,
onChanged: (bool isOn) {
print(isOn);
setState(() {
isInstructionView = isOn;
Global.shared.isInstructionView = isOn;
isOn =!isOn;
print(isInstructionView);
});
},
activeColor: Colors.blue,
inactiveTrackColor: Colors.grey,
inactiveThumbColor: Colors.grey,
),
),
);
}
}
class Global{
static final shared =Global();
bool isInstructionView = false;
}
Solution 2
You just need to make sure to declare the bool for the switch toggle outside Widget build to make it global and acessible for SetState method. No need to initstate and etc.
class ExampleClass extends StatefulWidget {
@override
_ExampleClassState createState() => _ExampleClassState();
}
class _ExampleClassState extends State<ExampleClass> {
bool isInstructionView = false;
@override
Widget build(BuildContext context) {
return Container(
child: Switch(
value: isInstructionView,
onChanged: (isOn) {
setState(() {
isInstructionView = isOn
});
print(isInstructionView);
},
...
),
);
}
}
Solution 3
Here Is my code for toggle button
class ToggleButtonScreen extends StatefulWidget {
@override
_ToggleButtonScreenState createState() => _ToggleButtonScreenState();
}
class _ToggleButtonScreenState extends State<ToggleButtonScreen> {
bool _value = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: _value ? AssetImage("images/cnw.png") : AssetImage("images/cnw.png"),
fit: BoxFit.cover,
),
),
child: Padding(
padding: EdgeInsets.all(AppDimens.EDGE_REGULAR),
child: Column(
children: [
// _customSwitchButton(),
_normalToggleButton(),
],
),
),
),
),
),
);
}
Widget _normalToggleButton () {
return Container(
child: Transform.scale(
scale: 2.0,
child: Switch(
activeColor : Colors.greenAccent,
inactiveThumbColor: Colors.redAccent,
value: _value,
activeThumbImage: AssetImage("images/cnw.png"),
inactiveThumbImage : AssetImage("images/simple_interest.png"),
onChanged: (bool value){
setState(() {
_value = value;
});
},
),
),
);
}
}
Solution 4
class Tab_b extends StatefulWidget {
bool isInstructionView = false;
@override
State<StatefulWidget> createState() => new _TabsPageState();
}
class _TabsPageState extends State<Tab_b>{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("add data"),
),
body: new Container(
child: Switch(
value: widget.isInstructionView,
onChanged: (bool isOn) {
print(isOn);
setState(() {
widget.isInstructionView = isOn;
print(widget.isInstructionView);
});
},
activeColor: Colors.blue,
inactiveTrackColor: Colors.grey,
inactiveThumbColor: Colors.grey,
),
),
);
}
Solution 5
You need to rebuild the widget when the state changes. refer the documentation https://docs.flutter.io/flutter/material/Switch/onChanged.html
Josh Kahane
Updated on December 06, 2022Comments
-
Josh Kahane over 1 year
When using the following
Switch
widget, theisOn
value always returnstrue
and never changes.The
Switch
only moves position on a swipe too, a tap won't move it. How to resolve?bool isInstructionView = false; Switch( value: isInstructionView, onChanged: (bool isOn) { setState(() { isInstructionView = isOn; print(isInstructionView); }); }, activeColor: Colors.blue, inactiveTrackColor: Colors.grey, inactiveThumbColor: Colors.grey, )
Update: For extra clarity,
onChanged
always returnsisOn
astrue
. Why would this be? -
Josh Kahane over 5 yearsThanks, but it makes no difference it being declared there. I can swap it there like so:
isInstructionView = !isInstructionView;
. The issue isisOn
doesn't change, its always provided astrue
. -
Zulfiqar over 5 yearsIt return always true because of when you setState it change isInstructionView value to false and this value is assigned to switch value i.e. it return again it's initial state.
-
Josh Kahane over 5 yearsI'm sure I understand, but even with your change, it doesn't affect it because 'isOn' value returned by
onChanged
never changes. -
Abdullah Bahattab over 2 years@JoshKahane This code works for me I just move
bool isInstructionView = false;
under my main class then I called it like thisvalue: widget.isInstructionView,
then insetState()
i calledwidget.isInstructionView = isOn