I'm new to Flutter and I'm trying to understand recomposition.
I have a list of items with edit buttons. When the edit button is clicked, a popup modal form appears with two textboxes and a checkbox. I can't get the checkbox to update when it's clicked. What am I doing wrong?
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Two ListViews',
theme: ThemeData(
primarySwatch: Colors.blue,
primaryColor: const Color(0xFF2196f3),
canvasColor: const Color(0xFFfafafa),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key, key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _titleController = TextEditingController();
final TextEditingController _descriptionController = TextEditingController();
bool _checkbox = false;
void _showForm() async {
showModalBottomSheet(
context: context,
elevation: 5,
isScrollControlled: true,
builder: (_) => Container(
padding: EdgeInsets.only(
top: 15,
left: 15,
right: 15,
// this will prevent the soft keyboard from covering the text fields
bottom: MediaQuery.of(context).viewInsets.bottom 120,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
controller: _titleController,
decoration: const InputDecoration(hintText: 'Title'),
),
const SizedBox(
height: 10,
),
TextField(
controller: _descriptionController,
decoration: const InputDecoration(hintText: 'Description'),
),
Row(
children: <Widget>[
const SizedBox(
width: 10,
),
const Text(
'Item is Checked: ',
style: TextStyle(fontSize: 17.0),
),
const SizedBox(width: 10),
// *********** Checkbox won't update on screen **********
// But the value toggles correctly in the print statement
Checkbox(
value: _checkbox,
onChanged: (value) {
setState(() {
_checkbox = !_checkbox;
print("*** isSwitched = $_checkbox");
});
},
),
],
),
],
),
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Pop-Up Checkbox'),
),
body:
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(
child:
ListView(
padding: EdgeInsets.all(10),
children: [
Card(
child: ListTile(
title: Text("List Item 1"),
trailing: SizedBox(
width: 100,
child: IconButton(
icon: const Icon(Icons.edit),
onPressed: () => _showForm(),
),
),
),
),
],
),
),
]
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => _showForm(),
),
);
}
} // End class _MyHomePageState
Thanks for your help!
Jason
CodePudding user response:
Hey setState will not update state of bottom sheet because bottom sheet is not part of your StatefulWidget for this you need to use StatefulBuilder
and then call setState like below-
void _showForm() async {
showModalBottomSheet(
context: context,
elevation: 5,
isScrollControlled: true,
builder: (_) => StatefulBuilder(builder: (BuildContext context, StateSetter myState) =>Container(
padding: EdgeInsets.only(
top: 15,
left: 15,
right: 15,
// this will prevent the soft keyboard from covering the text fields
bottom: MediaQuery.of(context).viewInsets.bottom 120,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
controller: _titleController,
decoration: const InputDecoration(hintText: 'Title'),
),
const SizedBox(
height: 10,
),
TextField(
controller: _descriptionController,
decoration: const InputDecoration(hintText: 'Description'),
),
Row(
children: <Widget>[
const SizedBox(
width: 10,
),
const Text(
'Item is Checked: ',
style: TextStyle(fontSize: 17.0),
),
const SizedBox(width: 10),
// *********** Checkbox won't update on screen **********
// But the value toggles correctly in the print statement
Checkbox(
value: _checkbox,
onChanged: (value) {
myState(() {
_checkbox = !_checkbox;
print("*** isSwitched = $_checkbox");
});
},
),
],
),
],
),
),
),
);
}