【问题标题】:Flutter => showDialog / AlertDialog => No MaterialLocalizations foundFlutter => showDialog / AlertDialog => 未找到 MaterialLocalizations
【发布时间】:2019-05-30 19:16:40
【问题描述】:

刚接触 Flutter,但印象非常深刻。 如果 PushNotification 通过 Firebase“onMessage”到达,我想显示一个对话框。

但每次我得到一个异常“没有找到 MaterialLocalizations”。如果试图显示我的对话框。 为了测试,我添加了一个 RaisedButton 来显示这个警报,但同样的问题。 也许有人可以帮助我。 非常感谢!!!

这是我的小应用程序的全部代码:

import 'dart:async';

import 'package:firebase_messaging/firebase_messaging.dart';

import 'package:flutter/material.dart';

void main() => runApp(Main());

class Main extends StatefulWidget {
  @override
  _MainState createState() => _MainState();
}

class _MainState extends State<Main> {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

  Widget _buildDialog(BuildContext context) {
    print("_buildDialog");
    return AlertDialog(
      content: Text("Item  has been updated"),
      actions: <Widget>[
        FlatButton(
          child: const Text('CLOSE'),
          onPressed: () {
            Navigator.pop(context, false);
          },
        ),
        FlatButton(
          child: const Text('SHOW'),
          onPressed: () {
            Navigator.pop(context, true);
          },
        ),
      ],
    );
  }

  void _showPushDialog() {
    print("DIALOG");
    showDialog<bool>(
      context: context,
      builder: (_) => _buildDialog(context),
    ).then((bool shouldNavigate) {
      if (shouldNavigate == true) {
        _navigateToPushDetail();
      }
    });
  }

  void _navigateToPushDetail() {
    print("TODO: Goto...");
  }

  @override
  void initState() {
    super.initState();
    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        //_neverSatisfied();
        _showPushDialog();
      },
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        _navigateToPushDetail();
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
        _navigateToPushDetail();
      },
    );

    _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(sound: true, badge: true, alert: true));
    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) {
      print("Settings registered: $settings");
    });
    _firebaseMessaging.getToken().then((String token) {
      assert(token != null);
      print("Push Messaging token: $token");
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: new Material(
          child: Column(children: <Widget>[
            Center(
              child: Text('Hello World'),
            ),
            RaisedButton(
              onPressed: () {
                print("pushed?");
                _showPushDialog();
              },
              child: Text("press me"),
            )
          ]),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter


    【解决方案1】:

    为了修复错误,您需要调用 Main 类作为 MaterialApp 的主参数,如下所示。

    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Welcome to Flutter',
          debugShowCheckedModeBanner: false,
          home: Main(),
        );
      }
    }
    

    & 将 Main 类中的构建方法更新为:

    @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Welcome to Flutter'),
          ),
          body: Column(children: <Widget>[
            Center(
              child: Text('Hello World'),
            ),
            RaisedButton(
              onPressed: () {
                print("pushed?");
                _showPushDialog(context);
              },
              child: Text("press me"),
            )
          ]),
        );
      }
    

    【讨论】:

    • 但是您没有解释原因...原因是您在Main 应用程序中收到的context 参数位于MaterialApp 小部件上方,即对话框使用的上下文,因此对Localizations.localeOf(context) 的任何搜索都将从MaterialApp 上方开始搜索,MaterialApp 是设置本地化的小部件。实际上,解决此问题的另一种方法是在两者之间放置一个 Builder 小部件。
    【解决方案2】:

    颤振 1.0,飞镖 2.x

    此解决方案适用于 StatelessWidget 小部件和 StatefulWidget 小部件。

    在顶部,您可以在声明中创建静态navKey

    class MyApp extends StatefulWidget {
      final String title; // sample var you want to pass to your widget
      static final navKey = new GlobalKey<NavigatorState>();
      const MyApp({Key navKey, this.title}) : super(key: navKey);
      @override
      State<StatefulWidget> createState() => _MyAppState();
    }
    

    在布局部分你应该使用key:

    return MaterialApp(
            navigatorKey:MyApp.navKey,
            title: widget.title,
            ...
    

    因此,当您需要对话框或其他小部件的当前上下文时,您可以在状态部分执行以下操作:

    @override
      void initState() {
      final context = MyApp.navKey.currentState.overlay.context;
      showMyCustomDialog(context);
      ...
      super.initState();
    }
    

    【讨论】:

      【解决方案3】:

      检查您的 MaterialApp() 小部件, 如果你设置localizationsDelegates,你可能会遇到这个问题。 当我删除这些代码时它可以工作。

                    localizationsDelegates: [
                        DefaultCupertinoLocalizations.delegate,
                    ],
      
      

      我的代码。

      MaterialApp(
                    navigatorKey: navigatorKey,
                    title: 'test',
                    theme: ThemeData(
                        platform: TargetPlatform.iOS,
                        backgroundColor: Color(0xfff1f1f1),
                        accentColor: AppStyle.colorPrimary,
                        primaryColor: AppStyle.colorPrimary,
                        buttonColor: AppStyle.colorPrimary,
                        iconTheme: IconThemeData(color: Colors.white),
                        textTheme: TextTheme(
                            title: TextStyle(color: Colors.white),
                        ),
                        primaryTextTheme: TextTheme(title: TextStyle(color: Colors.white)),
                        primaryIconTheme: const IconThemeData.fallback().copyWith(
                            color: Colors.white,
                        ),
                        appBarTheme: AppBarTheme().copyWith(brightness: Brightness.dark),
                    ),
                    home: LoginPage(),
                    debugShowCheckedModeBanner: false,
                    onGenerateRoute: AppRouter.router.generator,
                )
      
      

      【讨论】:

        猜你喜欢
        • 2021-03-15
        • 2023-03-07
        • 2021-11-03
        • 2021-03-27
        • 2019-04-27
        • 1970-01-01
        • 2021-07-29
        • 1970-01-01
        • 2022-01-25
        相关资源
        最近更新 更多