MaterialApp 之上的 Flutter 重建提供者
Flutter rebuild provider above MaterialApp
在我的应用程序中,我在 MaterialApp
上方定义了一个提供程序 Song
,以便通过我的应用程序访问它。
需要: 我这样做是因为我有一个 PageA
,其中包含一个 songTitle
变量和一个转到 PageB
的按钮。
在 PageB
上,我有一个按钮可以调用我的提供商 Song
并更新 PageA
。因此,当我在 PageB
上执行 Navigator.pop (context)
时,我回到 PageA
并查看更新后的 songTitle
变量。
为了能够从 PageB
更新 PageA
,我必须将我的提供商 Song
置于 MaterialApp
.
之上
==> 有效。
我的问题: 我希望能够在调用 PageA
时重置我的提供商。因此,如果我的 songTitle
变量已更新并且我退出 pageA
,我希望我的 songTitle
变量在初始化提供者 Song
时 return 为其默认值.目前 songTitle
变量一直保持更新 ...
这里是路由器:
abstract class RouterClass{
static Route<dynamic> generate(RouteSettings settings){
final args = settings.arguments;
switch(settings.name){
case RouterName.kMenu:
return CupertinoPageRoute(
builder: (context) => Menu()
);
case RouterName.kPageA:
return CupertinoPageRoute(
builder: (context) => PageA()
);
case RouterName.kPageB:
return CupertinoPageRoute(
builder: (context) => PageB()
);
default:
return CupertinoPageRoute(
builder: (context) => Error404View(title: "Error")
);
}
}
}
菜单:
class Menu extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body : Center(
child: MaterialButton(
onPressed: () {
Navigator.pushNamed(
context,
RouterName.kPageA,
),
},
child: Text('Button'),
),
),
),
);
}
}
A页:
class PageA extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('pageA'),
),
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.pushNamed(
context,
RouterName.kPageB,
),
child: Text('Button'),
),
],
);
}),
),
),
);
}
}
页面B:
class PageB extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('pageB'),
),
body : Center(
child: MaterialButton(
onPressed: () {
Provider.of<Song>(context, listen: false).updateSongTitle('New Title');
},
child: Text('Button'),
),
),
),
);
}
}
提供商宋:
class Song extends ChangeNotifier {
late String songTitle;
Song(){
_initialise();
}
Future _initialise() async
{
songTitle = "Title";
notifyListeners();
}
void updateSongTitle(String newTitle) {
songTitle = newTitle;
notifyListeners();
}
}
在页面 A 中使用 create
:
child: ChangeNotifierProvider(
create: (_) => Song(),
child: Consumer<Song>(
builder: (context, song, child) {
print('Consumer() : ${song.songTitle}');
...
将您的 song
对象传递给 PageB
:
Navigator.pushNamed(
context,
'/pageB',
arguments: song,
);
在页面 B 中获取 song
:
final song = ModalRoute.of(context)!.settings.arguments as Song;
完整代码:
// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
'/': (_) => const HomePage(),
'/pageA': (_) => const PageA(),
'/pageB': (_) => const PageB(),
},
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
'/pageA',
);
},
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
),
);
}
}
class PageA extends StatefulWidget {
const PageA({Key? key}) : super(key: key);
@override
State<PageA> createState() => _PageAState();
}
class _PageAState extends State<PageA> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ChangeNotifierProvider(
create: (_) => Song(),
child: Consumer<Song>(
builder: (context, song, child) {
print('Consumer() : ${song.songTitle}');
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// SONG TITLE
Text(song.songTitle),
// Button
MaterialButton(
onPressed: () {
Navigator.pushNamed(
context,
'/pageB',
arguments: song,
);
},
child: const Text('Button'),
),
],
);
},
),
),
),
);
}
}
class PageB extends StatelessWidget {
const PageB({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final song = ModalRoute.of(context)!.settings.arguments as Song;
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: const Text('pageB'),
),
body: Center(
child: MaterialButton(
onPressed: () {
song.updateSongTitle('New Title');
},
child: const Text('Button'),
),
),
),
);
}
}
class Song extends ChangeNotifier {
late String songTitle;
Song() {
_initialise();
}
Future _initialise() async {
songTitle = "Title";
notifyListeners();
}
void updateSongTitle(String newTitle) {
songTitle = newTitle;
notifyListeners();
}
}
在我的应用程序中,我在 MaterialApp
上方定义了一个提供程序 Song
,以便通过我的应用程序访问它。
需要: 我这样做是因为我有一个 PageA
,其中包含一个 songTitle
变量和一个转到 PageB
的按钮。
在 PageB
上,我有一个按钮可以调用我的提供商 Song
并更新 PageA
。因此,当我在 PageB
上执行 Navigator.pop (context)
时,我回到 PageA
并查看更新后的 songTitle
变量。
为了能够从 PageB
更新 PageA
,我必须将我的提供商 Song
置于 MaterialApp
.
==> 有效。
我的问题: 我希望能够在调用 PageA
时重置我的提供商。因此,如果我的 songTitle
变量已更新并且我退出 pageA
,我希望我的 songTitle
变量在初始化提供者 Song
时 return 为其默认值.目前 songTitle
变量一直保持更新 ...
这里是路由器:
abstract class RouterClass{
static Route<dynamic> generate(RouteSettings settings){
final args = settings.arguments;
switch(settings.name){
case RouterName.kMenu:
return CupertinoPageRoute(
builder: (context) => Menu()
);
case RouterName.kPageA:
return CupertinoPageRoute(
builder: (context) => PageA()
);
case RouterName.kPageB:
return CupertinoPageRoute(
builder: (context) => PageB()
);
default:
return CupertinoPageRoute(
builder: (context) => Error404View(title: "Error")
);
}
}
}
菜单:
class Menu extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body : Center(
child: MaterialButton(
onPressed: () {
Navigator.pushNamed(
context,
RouterName.kPageA,
),
},
child: Text('Button'),
),
),
),
);
}
}
A页:
class PageA extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('pageA'),
),
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.pushNamed(
context,
RouterName.kPageB,
),
child: Text('Button'),
),
],
);
}),
),
),
);
}
}
页面B:
class PageB extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('pageB'),
),
body : Center(
child: MaterialButton(
onPressed: () {
Provider.of<Song>(context, listen: false).updateSongTitle('New Title');
},
child: Text('Button'),
),
),
),
);
}
}
提供商宋:
class Song extends ChangeNotifier {
late String songTitle;
Song(){
_initialise();
}
Future _initialise() async
{
songTitle = "Title";
notifyListeners();
}
void updateSongTitle(String newTitle) {
songTitle = newTitle;
notifyListeners();
}
}
在页面 A 中使用 create
:
child: ChangeNotifierProvider(
create: (_) => Song(),
child: Consumer<Song>(
builder: (context, song, child) {
print('Consumer() : ${song.songTitle}');
...
将您的 song
对象传递给 PageB
:
Navigator.pushNamed(
context,
'/pageB',
arguments: song,
);
在页面 B 中获取 song
:
final song = ModalRoute.of(context)!.settings.arguments as Song;
完整代码:
// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
'/': (_) => const HomePage(),
'/pageA': (_) => const PageA(),
'/pageB': (_) => const PageB(),
},
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
'/pageA',
);
},
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
),
);
}
}
class PageA extends StatefulWidget {
const PageA({Key? key}) : super(key: key);
@override
State<PageA> createState() => _PageAState();
}
class _PageAState extends State<PageA> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ChangeNotifierProvider(
create: (_) => Song(),
child: Consumer<Song>(
builder: (context, song, child) {
print('Consumer() : ${song.songTitle}');
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// SONG TITLE
Text(song.songTitle),
// Button
MaterialButton(
onPressed: () {
Navigator.pushNamed(
context,
'/pageB',
arguments: song,
);
},
child: const Text('Button'),
),
],
);
},
),
),
),
);
}
}
class PageB extends StatelessWidget {
const PageB({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final song = ModalRoute.of(context)!.settings.arguments as Song;
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: const Text('pageB'),
),
body: Center(
child: MaterialButton(
onPressed: () {
song.updateSongTitle('New Title');
},
child: const Text('Button'),
),
),
),
);
}
}
class Song extends ChangeNotifier {
late String songTitle;
Song() {
_initialise();
}
Future _initialise() async {
songTitle = "Title";
notifyListeners();
}
void updateSongTitle(String newTitle) {
songTitle = newTitle;
notifyListeners();
}
}