static list in FirstScreen.dart
static List<Shoe> shoeBank = [
Shoe(iN:0,b: "Red Shoe", i: "assets/nikeShoeProduct1.jpg", q: 0,c: Color(0xFFC60635)),
Shoe(iN:1,b: "White Shoe", i: "assets/nikeShoeProduct2.jpg", q: 0, c: Colors.white)
];
I am changing one of the item value int
from ThirdScreen.dart
in the list. It does change in the list
but does not show the updated value in the SecondScreen.dart
screen? However, when I go back all the way to FirstScreen.dart
then it does show the updated value in the second screen.
I have tried using SetState in the ThirdScreen.dart while updating the value.
*How to make the SecondScreen.dart
show the updated value when came back from ThirdScreen.dart
and what might went wrong?
For a clean solution you need to make Store
class that holds the list along with the list manipulation methods, then use a provider
package for example to listen to all the changes that happens to the list.
Here is a small example:
class Store extends ChangeNotifier {
var myList = <String>[];
void add() {
myList.add('new item');
notifyListeners();
}
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
var pageNumber = 1;
return MaterialApp(
home: Scaffold(
body: ChangeNotifierProvider(
create: (_) => Store(),
child: pageNumber == 1 ? FirstPage() : SecondPage(),
),
),
);
}
}
class FirstPage extends StatelessWidget {
const FirstPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
var store = Provider.of<Store>(context);
return Center(
child: RaisedButton(onPressed: () => store.add()),
);
}
}
class SecondPage extends StatelessWidget {
const SecondPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
var store = Provider.of<Store>(context);
return Column(
children: [
...store.myList.map((item) => Text(item)).toList(),
],
);
}
}
As Nour already pointed out you should make a Model class which holds your List<Shoe>
. A static
variable to store some changing data is never the way you should go.
The steps I would recommend are the following:
Create a model class like ShoeStore
which extends ChangeNotifier
In this class you store you List<Shoe>
and you write your methods to change this list. Important is that at the end of the methods you call notifyListeners
.
As the parent of your MaterialApp
you create a MultiProvider
widget where you initialize the ShoeStore
There, where you need to access the ShoeStore
you provide the widget Cosumer<ShoeStore>
. And instead of a child you insert your children there in a builder
property which gets the ShoeStore
instance as an argument.
Read this great guide! about Statemanagement with Provider for Flutter.
This is how your code could look like:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) =>
ShoeStore([Shoe(name: "Nike"), Shoe(name: "Adidas")]),
),
],
child: MaterialApp(
home: Column(
children: [
Expanded(child: FirstScreen()),
Expanded(child: SecondScreen()),
Expanded(child: ThirdScreen())
],
),
),
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
height: 100,
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<ShoeStore>(
builder: (context, shoeStore, child) => Container(
alignment: Alignment.center,
color: Colors.blue,
height: 100,
child: Text("Number of shoes: ${shoeStore.shoes.length}",
style: Theme.of(context).textTheme.headline4),
),
);
}
}
class ThirdScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<ShoeStore>(
builder: (context, shoeStore, child) => Container(
constraints: BoxConstraints.expand(),
color: Colors.green,
height: 100,
child: FlatButton(
child: Text(
"Add Shoe",
style: TextStyle(color: Colors.black),
),
onPressed: () => shoeStore.addShoe(Shoe(name: "Bugatti")),
),
),
);
}
}
class ShoeStore extends ChangeNotifier {
List<Shoe> _shoes;
ShoeStore(List<Shoe> initialValue) {
_shoes = initialValue;
}
List<Shoe> get shoes => _shoes;
void addShoe(Shoe shoe) {
_shoes.add(shoe);
notifyListeners();
}
}
class Shoe {
String name;
Shoe({this.name});
}
As you can see. The FirstScreen
is now empty and you do not have to store you List there anymore.
Without any package I would inject the State
of my App into the Widgets which have to read or write the fields of the state.
This would look like:
class MyApp extends StatefulWidget {
@override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<Shoe> _shoes = [Shoe(name: "Nike"), Shoe(name: "Adidas")];
void addShoe(Shoe shoe) => setState(() {
_shoes.add(shoe);
});
List<Shoe> get shoes => _shoes;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Column(
children: [
Expanded(child: FirstScreen()),
Expanded(child: SecondScreen(this)),
Expanded(child: ThirdScreen(this))
],
),
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
height: 100,
);
}
}
class SecondScreen extends StatelessWidget {
final MyAppState appState;
SecondScreen(this.appState);
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
color: Colors.blue,
height: 100,
child: Text("Number of shoes: ${appState.shoes.length}",
style: Theme.of(context).textTheme.headline4),
);
}
}
class ThirdScreen extends StatelessWidget {
final MyAppState appState;
ThirdScreen(this.appState);
@override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints.expand(),
color: Colors.green,
height: 100,
child: FlatButton(
child: Text(
"Add Shoe",
style: TextStyle(color: Colors.black),
),
onPressed: () => appState.addShoe(Shoe(name: "Bugatti")),
),
);
}
}
class Shoe {
String name;
Shoe({this.name});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.