'Flutter SwitchListTile won't switch despite stateful widget
I'm trying to create a sort of modal to create a chat room that can be either private or public, and I'm trying to add a toggle that will unveil a text input when activated. I'm running into an unknown issue where the toggle is stuck and won't switch state. Here's my code, any help is much appreciated!
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
List<GameRoom> roomList = [
GameRoom("Room test 1", "guy 1", false),
GameRoom("Private Room 1", "guy 2", true, "password")
];
final _inputController = TextEditingController();
bool isRoomProtected = false;
return Scaffold(
appBar: AppBar(
title: Text("Welcome, ${globals.username}"),
),
floatingActionButton: FloatingActionButton.extended(
label: const Text("Create room"),
icon: const Icon(Icons.add),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("Create de salle"),
TextField(
controller: _inputController,
maxLines: 1,
decoration: const InputDecoration(
labelText: 'Room name',
),
),
SwitchListTile(
title: const Text("Make room private"),
secondary: const Icon(Icons.lock),
value: isRoomProtected,
onChanged: (bool value) => setState(() {
print("test");
isRoomProtected = value;
}),
),
TextButton(onPressed: () {}, child: const Text("Ok !")),
],
);
});
}),
body: Column(
children: [
TextButton(onPressed: () {}, child: Text("put searchbar here")),
Column(
children: [
for (GameRoom room in roomList)
Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(room.hasPassword ? Icons.lock : Icons.lock_open),
title: Text(room.name),
subtitle: Text("owner : ${room.owner}"),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 10.0, right: 10.0),
child: TextButton(
child: const Text('Join room'),
onPressed: () {/* ... */},
),
),
],
),
],
),
)
],
),
],
),
);
}
}
Solution 1:[1]
Answer: I needed to add StatefulBuilder. I also wrapped the switch in a column, added a textField wrapped in a visibility and a box of the same sized wrapped in a visibility configured to appear when the textField isn't visible. This makes it so there's no jitter when toggling on and off.
StatefulBuilder(
builder: (BuildContext context, StateSetter stateSetter) {
return Column(
children: [
SwitchListTile(
title: const Text("Lock room with password"),
value: lockedRoom,
onChanged: (val) {
stateSetter(() => lockedRoom = val);
},
secondary: Icon(lockedRoom ? Icons.lock : Icons.lock_open),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Visibility(
visible: lockedRoom,
child: TextField(
controller: _roomPasswordController,
maxLines: 1,
decoration: const InputDecoration(
labelText: 'Room password',
),
),
),
),
Visibility(
visible: !lockedRoom,
child: Container(
height: 52,
),
),
],
);
},
),
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Tom |
