Reputation: 7966
I'm working with Provider
provider: ^4.1.2
I had 2 pages : A, B.
Page A and B show same simple design, with below codes :
PageA.dart
class PageA extends StatelessWidget {
var songTitle = '';
@override
Widget build(BuildContext c) {
return Column(children: <Widget>[
FloatingActionButton.extended(
onPressed: () {
// LOGIC : TRANSFER TO PAGE B AFTER CLICKED BUTTON FROM PAGE A
Navigator.push(context, MaterialPageRoute(
builder: (context) => PageB()));
},
label: Text('Click'),
),
),
Text('$songTitle');
// STEP 2 : while page B already got `songTitle`
// to show on UI, I want `songTitle` also update on this page A
// in the same time
]);
}
}
PageB.dart
class PageB extends StatelessWidget {
var songTitle = '';
@override
Widget build(BuildContext c) {
return Text('$songTitle');
}
@override
void initState() {
super.initState();
// LOGIC : CALL API TO GET `songTitle` TO UPDATE ON UI
api.request().then((title) {
setState(() {
this.songTitle = title;
// STEP 1 : this causes update to page B
// show `songTitle` got from api success
});
});
}
}
These codes run with no bugs.
What I want is after
Step 1
gotsongTitle
data,It will updated its data to page A (
Step 2
) and page B (Step 1
) in the same time by usingProvider
(ex.Provider.of(context)
...)
People who knows,
Please tell me,
Thank you,
UPDATED I got correct @Chichebe answer in below already.
Upvotes: 2
Views: 6385
Reputation: 598
main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [ChangeNotifierProvider<Song>(create: (context) => Song())],
child: MaterialApp(home: PageA()),
);
}
}
Song Model
class Song extends ChangeNotifier {
String songTitle = 'Title';
void updateSongTitle(String newTitle) {
songTitle = newTitle;
notifyListeners();
}
}
pageA
class PageA extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Consumer<Song>(builder: (context, song, child) {
print('Consumer() : ${song.songTitle}');
return Column(
children: <Widget>[
// SONG TITLE
Text(song.songTitle),
// Button
MaterialButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => PageB()),
),
child: Text('Button'),
),
],
mainAxisAlignment: MainAxisAlignment.center,
);
}),
),
);
}
}
pageB
class PageB extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return PageBState();
}
}
class PageBState extends State<PageB> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
Timer(Duration(seconds: 2), () {
final song = Provider.of<Song>(context, listen: false);
song.updateSongTitle('New Title');
});
}
@override
Widget build(BuildContext c) {
return Container(
child: Text('Page B'),
color: Colors.white,
);
}
}
p/s :I understand that
- use the Provider package in managing your state and passing data down your widget tree.
- use ChangeNotifier alongside ChangeNotifierProvider to achieve this.
Upvotes: 3
Reputation: 1816
Have you read the Provider examples?
You could do something like that:
class Song{
String title;
Song(this.title);
}
class MyProvider extends ChangeNotifier{
Song song;
void getSongInformation(String song) async{
try{
final req = await doYourAPIRequest();
song = Song(req['title']);
notifyListeners(); // Notify the listeners about this change
}catch(e){
// handle the error
}
}
}
Then in your Widgets
Consumer<Song>(
builder: (context, song, child) {
return Text(song.title);
},
)
So any Widgets that is listening for Song changes will be notified about any changes when you call notifyListeners()
, if you only need the Provider to notify about a single Song change, then you can also use ValueNotifierProvider. Also, it's good practice to put your Consumer deep as possible in the Widget tree in order to rebuild only the Widgets that depends on that value.
Upvotes: 1