【问题标题】:Flutter rebuild provider above MaterialAppMaterialApp 之上的 Flutter 重建提供程序
【发布时间】:2022-01-10 17:58:50
【问题描述】:

在我的应用程序中,我在MaterialApp 上方定义了一个提供程序Song,以便通过我的应用程序访问它。


需要:我这样做是因为我有一个PageA,其中包含一个songTitle 变量和一个转到PageB 的按钮。 在PageB 上,我有一个按钮调用我的提供者Song 并更新PageA。因此,当我在PageB 上执行Navigator.pop (context) 时,我会回到PageA 并查看更新后的songTitle 变量。 为了能够从PageB 更新PageA,我必须将我的提供者Song 放在MaterialApp 上方。

==> 有效。


我的问题:我希望能够在致电PageA 时重置我的提供程序。因此,如果我的songTitle 变量已更新并且我退出pageA,我希望我的songTitle 变量在我初始化提供程序Song 时返回其默认值。目前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'),
                ),
              ],
            );
          }),
        ),
      ),
    );
  }
}

PageB:

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();
  }
}

【问题讨论】:

    标签: flutter dart provider


    【解决方案1】:

    在 PageA 中使用 create

    child: ChangeNotifierProvider(
      create: (_) => Song(),
      child: Consumer<Song>(
        builder: (context, song, child) {
          print('Consumer() : ${song.songTitle}');
    ...
    

    将您的song 对象传递给PageB

    Navigator.pushNamed(
      context,
      '/pageB',
      arguments: song,
    );
    

    在PageB中获取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();
      }
    }
    

    【讨论】:

    • 感谢您的帮助,非常感谢。我需要在参数路由中传递以前的提供者。
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 2019-12-24
    • 2021-12-15
    • 2020-07-29
    • 2020-04-12
    • 2022-01-14
    • 2020-11-18
    • 2023-03-22
    相关资源
    最近更新 更多