Reputation: 702
I have a main screen containing a pageview. The pageview has three children, each being a separate class:
children: <Widget>[
FirstScreen(),
SecondScreen(),
ThirdScreen(),
These screens load data from a database and are StatefulWidgets. I add data to that database from a separate screen that I open on my main screen.
I want to trigger the setState
method for these three screens after I add the data to the database.
How do I access these screens when they are in a different class?
Upvotes: 0
Views: 2277
Reputation: 3073
I added this to show the example, modify this for your database !
Main Screen
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
List<Map> list = [];
@override
void initState() {
super.initState();
list.add({'name': 'Raj', 'phone': '1234567890'});
list.add(
{'name': 'Naveen', 'phone': '1122334455'},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('Main Screen', style: TextStyle(color: Colors.white)),
actions: [
IconButton(
icon: Icon(Icons.add_circle, color: Colors.white),
onPressed: () {
addNewItem();
})
]),
body: Container(
padding:EdgeInsets.all(15),
color: Colors.white,
child: Center(
child: ListView.builder(
itemCount: list.length,
itemBuilder: (con, ind) {
return ListTile(
title: Text(list[ind]['name'],
style: TextStyle(color: Colors.black)),
subtitle: Text(list[ind]['phone'],
style: TextStyle(color: Colors.black)));
}),
)),
);
}
void addNewItem() async {
Map newItem = await Navigator.push(
context, MaterialPageRoute(builder: (cc) => NewScreen()));
if (newItem != null) {
setState(() {
list.add(newItem);
});
}
}
}
class NewScreen extends StatefulWidget {
@override
_NewScreenState createState() => _NewScreenState();
}
class _NewScreenState extends State<NewScreen> {
//Declare your new item here....
Map newItem;
//I m using strigns, but use TextEditingControllers here...
String name = '', phone = '';
@override
void initState() {
super.initState();
//database initialisation...
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: onBackPressed,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('New Screen', style: TextStyle(color: Colors.white)),),
body: Container(
padding:EdgeInsets.all(15),
color:Colors.white,
child: Center(
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Name',
labelStyle: TextStyle(color: Colors.black)),
onChanged: (v) {
setState(() {
name = v;
});
},
style: TextStyle(color: Colors.black)),
TextField(
decoration: InputDecoration(labelText: 'Phone',
labelStyle: TextStyle(color: Colors.black)),
onChanged: (v) {
setState(() {
phone = v;
});
},
style: TextStyle(color: Colors.black)),
RaisedButton(
child: Text('Add'),
onPressed: () {
if (name.isNotEmpty && phone.isNotEmpty) {
newItem = Map();
newItem['name'] = name;
newItem['phone'] = phone;
//You may close new screen if you want !
//But call sendNewItemBack();
}
})
],
))),
),
);
}
Future<bool> onBackPressed() async {
sendNewItemBack();
}
sendNewItemBack() {
//add new item to database
Navigator.of(context).pop(newItem);
}
}
After Adding
Upvotes: 0
Reputation: 116
What you are looking for is State management.
There are various possibilities to ensure communication between business logic / storages and widgets.
https://flutter.dev/docs/development/data-and-backend/state-mgmt/options
I can recommend BLoC and BlocProvider for state management. In simple words it allows your widgets to react on particular events, state changes in your app and separates business logic from views.
https://pub.dev/packages/flutter_bloc
Upvotes: 1