问题
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.
回答1:
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.
回答2:
Have you read the Provider examples?
- In flutter don't let your widgets handle logic operations, such as making API requests, you could do that in your provider, and even better create an independent class that will handle HTTP requests for you, then you inject it in your provider code,
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.
来源:https://stackoverflow.com/questions/62148419/is-possible-update-value-cross-pages-by-using-provider-in-flutter