我有一个简单的目标要实现。我的应用程序中有 2 个屏幕,在主屏幕上有一个按钮,可以将我导航到一个名为“兴趣”的新页面。兴趣页面是一个复选框列表(我只能使用 listview.builder)和一个提交数据的按钮(将我导航回主屏幕)。我想要实现的目标是:
- 复选框应该可以正常工作。
- 当我从“兴趣”页面导航到主页并再次导航回“兴趣”页面时,所选的复选框应保持选中状态。简而言之,应该保存页面的状态。
- 我编写了一个函数“applyInterestChanges”来将数据保存在数据库中。我必须检索相同的数据来显示选定的复选框(我们是通过构造函数传递数据来完成的)。
如有任何帮助,我们将不胜感激!!
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Interests(),
),
);
},
child: Text("Click here!!"),
),
),
),
);
}
}
class Interests extends StatefulWidget {
final List<dynamic> selectedList;
final void Function(List<dynamic>) callback;
Interests(this.selectedList, this.callback);
@override
_InterestsState createState() => _InterestsState();
}
class _InterestsState extends State<Interests> {
Map<String, dynamic> _categories = {
"responseCode": "1",
"responseText": "List categories.",
"responseBody": [
{"category_id": "1", "category_name": "Movies"},
{"category_id": "2", "category_name": "Sports"},
{"category_id": "3", "category_name": "Food"},
{"category_id": "4", "category_name": "Music"},
{"category_id": "5", "category_name": "Others"},
],
"responseTotalResult": 5
};
void _onCategorySelected(bool selected, categoryName) {
if (selected == true) {
setState(() {
widget.selectedList.add(categoryName);
});
} else {
setState(() {
widget.selectedList.remove(categoryName);
});
}
widget.callback(widget.selectedList);
}
applyInterestChanges() { //function to save the changes in database.
Firestore.instance
.collection('my_users')
.document(currentUserModel.id)
.updateData({
"interests": widget.selectedList,
});
} //this code is working properly. Need to similar function to retrieve the data and display the updated interests list.
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Interests"),
),
body: SingleChildScrollView(
child: Column(
children: [
Text(
"Select your interests: ",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _categories['responseTotalResult'],
itemBuilder: (BuildContext context, int index) {
return CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
value: widget.selectedList.contains(
_categories['responseBody'][index]['category_name']),
onChanged: (bool selected) {
_onCategorySelected(selected,
_categories['responseBody'][index]['category_name']);
},
title:
Text(_categories['responseBody'][index]['category_name']),
);
},
),
MaterialButton(
onPressed: () {
Navigator.pop(context);
applyInterestChanges();
},
child: Text("Submit"),
),
],
),
),
);
}
}
最佳答案
您可以从父小部件MyHomeWidget
传递一个空列表,并通过Interests
小部件的回调更新此列表。
下次,每当您返回并再次导航到Interests
小部件时,我们都会传递此更新的列表,该列表保存Interests
小部件的状态。因此,将根据列表中的值来检查复选框。
这里是实现:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<dynamic> selectedList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Interests(
selectedList,
(List<dynamic> updatedList) {
setState(() {
selectedList = updatedList;
});
}
),
),
);
},
child: Text("Click here!!"),
),
),
),
);
}
}
class Interests extends StatefulWidget {
Interests(this.selectedList, this.callback);
// Passing the list from parent widget i.e, MyHomeWidget
// Initially the list will be empty
// We will update the list in parent whenever checkboxes change
final List<dynamic> selectedList;
// Creating a callback function to save state(update list) in
// MyHomeWidget
final void Function(List<dynamic>) callback;
@override
_InterestsState createState() => _InterestsState();
}
class _InterestsState extends State<Interests> {
Map<String, dynamic> _categories = {
"responseCode": "1",
"responseText": "List categories.",
"responseBody": [
{"category_id": "1", "category_name": "Movies"},
{"category_id": "2", "category_name": "Sports"},
{"category_id": "3", "category_name": "Food"},
{"category_id": "4", "category_name": "Music"},
{"category_id": "5", "category_name": "Others"},
],
"responseTotalResult": 5
};
void _onCategorySelected(bool selected, categoryId) {
if (selected == true) {
setState(() {
widget.selectedList.add(categoryId);
});
} else {
setState(() {
widget.selectedList.remove(categoryId);
});
}
// Callback to save the updated selectedList to MyHomeWidget list
widget.callback(widget.selectedList);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Interests"),
),
body: SingleChildScrollView(
child: Column(
children: [
Text(
"Select your interests: ",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _categories['responseTotalResult'],
itemBuilder: (BuildContext context, int index) {
return CheckboxListTile(
value: widget.selectedList.contains(
_categories['responseBody'][index]['category_id']),
onChanged: (bool selected) {
_onCategorySelected(selected,
_categories['responseBody'][index]['category_id']);
},
title:
Text(_categories['responseBody'][index]['category_name']),
);
},
),
RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Go back!!"),
),
],
),
),
);
}
}
这是您想要从 Firebase
获取的方法。我使用了更新后的类 FirebaseFirestore
。如果您使用的是旧版本的 Firebase
,只需将 FirebaseFirestore
替换为 Firebase
即可。
Future<void> fetchInterestChanges() async { //function to get the changes in database.
final DocumentSnapshot doc = await FirebaseFirestore.instance
.collection('my_users')
.document(currentUserModel.id)
.get();
final updatedList = doc.data();
print(updatedList);
}
关于firebase - Flutter:即使在屏幕之间导航后也会保存页面的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64842446/