TL; DR: как принудительно инициализировать состояние виджета
У меня есть список вложенных ExpansionTiles с PageStorageKey. У каждой плитки есть атрибут, который можно выбрать / отменить. Выбранные элементы добавляются в список и возвращаются на вызывающую страницу. Эта функция работает хорошо. Проблема в том, что когда я возвращаюсь на страницу выбора, она все еще сохраняет состояние ранее выбранных элементов. После перехода (всплытия) обратно на домашнюю страницу я хотел бы, чтобы все данные состояния, связанные со страницей выбора, были сброшены или удалены и повторно инициализированы.
Я добавил методы deactivate () и dispose (), но они все еще держась за государство. Я также добавил уникальный ключ, но это не помогло.
[домашняя страница ] [1]
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
var txtField = TextEditingController();
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Builder(
builder: (context) => Form(
child: Container(
color: Colors.grey[300],
padding: const EdgeInsets.all(20),
child: TextFormField(
controller: txtField,
onTap: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
OccupationSelection(),
),
);
txtField.text = result.toString();
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: const Icon(Icons.work),
labelText: 'Select an Occupation',
),
),
),
),
),
));
}
}
class OccupationSelection extends StatelessWidget {
final List<String> selectedOccupation = List<String>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Select An Occupation'),
),
body: ListView.builder(
itemCount: occupationDB.length,
itemBuilder: (BuildContext context, int index) => OccItem(
context,
occupationDB[index],
(String item) {
selectedOccupation.add(item);
},
(String item) {
selectedOccupation.remove(item);
},
),
),
floatingActionButton: FloatingActionButton(
child: Text('Save'),
onPressed: () {
Navigator.of(context).pop(selectedOccupation.join('+'));
},
),
);
}
}
// Create the Widget for the row
class OccItem extends StatefulWidget {
final Occupation entry;
final Function addOccupation;
final Function delOccupation;
final context;
OccItem(this.context, this.entry, this.addOccupation, this.delOccupation);
@override
OccItemState createState() => OccItemState();
}
class OccItemState extends State<OccItem> {
final Color _iconColor = Colors.black;
Widget _buildTiles(Occupation root) {
if (root.children.isEmpty) {
return Container(
color: Colors.grey[300],
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, top: 10.0, bottom: 20, right: 20),
child: ListTile(
//key: _key,
leading: IconButton(
icon: Icon(
root.occSelected
? Icons.check_box
: Icons.check_box_outline_blank,
color: _iconColor),
onPressed: () {
root.occSelected == false
? widget.addOccupation('${root.occId}${root.occTitle}')
: widget.delOccupation('${root.occId}${root.occTitle}');
root.occSelected = !root.occSelected;
setState(() {});
Scaffold.of(widget.context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(
content: root.occSelected
? Text(
'Occupation Selected ${root.occTitle}',
style: TextStyle(color: Colors.blueAccent),
)
: Text(
'Occupation Removed ${root.occTitle}',
style: TextStyle(color: Colors.redAccent),
),
duration: Duration(seconds: 4),
));
}),
title: Text(root.occTitle),
),
),
); //Detail item
}
return Container(
color: Colors.grey[300],
child: Padding(
padding:
const EdgeInsets.only(left: 20.0, top: 10.0, bottom: 20, right: 20),
child: ExpansionTile(
key: PageStorageKey<Occupation>(root),
title: Text(root.occTitle),
children: root.children.map<Widget>(_buildTiles).toList(),
),
),
); //High level item
}
void deactivate() {
super.deactivate();
}
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return _buildTiles(widget.entry);
}
}
class Occupation {
final String occId;
final String occTitle;
bool occSelected;
List<Occupation> children;
Occupation(this.occId, this.occTitle, this.occSelected,
[this.children = const <Occupation>[]]);
}
// Occupation Database
List<Occupation> occupationDB = <Occupation>[
Occupation(
'1.',
'Business',
false,
<Occupation>[
Occupation(
'1.1.',
'Management',
false,
<Occupation>[
Occupation('1.1.1.', 'Accounting', false),
Occupation('1.1.2.', 'Administration', false),
Occupation('1.1.3.', 'Business Development', false),
Occupation('1.1.4.', 'Finance | Financial Services | Securities', false),
Occupation('1.1.5.', 'Human Resources', false),
],
),
Occupation(
'1.2.',
'Construction | Architecture',
false,
<Occupation>[
Occupation('1.2.1.', 'Commercial', false),
Occupation('1.2.2.', 'Residential', false),
Occupation('1.2.3.', 'Design', false),
Occupation(
'1.2.4.',
'Trades',
false,
<Occupation>[
Occupation('1.2.4.1.', 'Brickmason | Blockmason', false),
Occupation('1.2.4.2.', 'Carpenter', false),
Occupation('1.2.4.3.', 'Cement Mason | Concrete Finisher', false),
Occupation('1.2.4.4.', 'Construction', false),
Occupation('1.2.4.5.', 'Electrician', false),
Occupation('1.2.4.6.', 'Glazier', false),
Occupation('1.2.4.7.', 'HVAC', false),
Occupation('1.2.4.8.', 'Iron', false),
Occupation('1.2.4.9.', 'Painter', false),
Occupation('1.2.4.10.', 'Plumber', false),
Occupation('1.2.4.11.', 'Welder', false),
],
),
],
),
],
), //Business
Occupation(
'2.',
'Education',
false,
<Occupation>[
Occupation('2.1.', 'Administration', false),
Occupation('2.2.', 'Athletics', false),
Occupation('2.3.', 'Curriculum Development', false),
Occupation(
'2.4.',
'Teaching',
false,
<Occupation>[
Occupation('2.4.1.', 'Pre-school', false),
Occupation('2.4.2.', 'Elementary', false),
Occupation('2.4.3.', 'Middle School', false),
Occupation('2.4.4.', 'High School', false),
],
),
],
), //Education
];