'No MaterialLocalizations found - MyApp widgets require MaterialLocalizations to be provided by a Localizations widget ancestor

I was just trying to create an app with button which shows an alert message when the button is pressed.

But it gives me this error(Mentioned below).

I wrote this code by taking reference of this video.

I am running the application on a live android phone using adb connect

Please help..!

Code

import 'package:flutter/material.dart';

void main(){
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Test",
      home: Scaffold(
        appBar: AppBar(title: Text("Test")),
        body: Container(
          child: Center(
            child: RaisedButton(
              color: Colors.redAccent,
              textColor: Colors.white,
              onPressed: (){testAlert(context);},
              child: Text("PressMe"),
            ),
          ),
        ),
      ),
    );
  }
  void testAlert(BuildContext context){
    var alert = AlertDialog(
      title: Text("Test"),
      content: Text("Done..!"),
    );

    showDialog(
        context: context,
        builder: (BuildContext context){
          return alert;
        }
    );
  }
}

This is the code that i wrote. I also tried inserting the contents of testAlert() function directly into onPressed but doesn't work.

Error

Performing hot reload...
Syncing files to device ZUK Z2131...
Reloaded 0 of 419 libraries in 1,929ms.
I/flutter (18652): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter (18652): The following assertion was thrown while handling a gesture:
I/flutter (18652): No MaterialLocalizations found.
I/flutter (18652): MyApp widgets require MaterialLocalizations to be provided by a Localizations widget ancestor.
I/flutter (18652): Localizations are used to generate many different messages, labels,and abbreviations which are used
I/flutter (18652): by the material library. 
I/flutter (18652): To introduce a MaterialLocalizations, either use a  MaterialApp at the root of your application to
I/flutter (18652): include them automatically, or add a Localization widget with a MaterialLocalizations delegate.
I/flutter (18652): The specific widget that could not find a MaterialLocalizations ancestor was:
I/flutter (18652):   MyApp
I/flutter (18652): The ancestors of this widget were:
I/flutter (18652):   [root]
I/flutter (18652): 
I/flutter (18652): When the exception was thrown, this was the stack:
I/flutter (18652): #0      debugCheckHasMaterialLocalizations.<anonymous closure> (package:flutter/src/material/debug.dart:124:7)
I/flutter (18652): #1      debugCheckHasMaterialLocalizations (package:flutter/src/material/debug.dart:127:4)
I/flutter (18652): #2      showDialog (package:flutter/src/material/dialog.dart:635:10)
I/flutter (18652): #3      MyApp.testAlert (package:flutter_app/main.dart:33:5)
I/flutter (18652): #4      MyApp.build.<anonymous closure> (package:flutter_app/main.dart:19:29)
I/flutter (18652): #5      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:507:14)
I/flutter (18652): #6      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:562:30)
I/flutter (18652): #7      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
I/flutter (18652): #8      TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:242:9)
I/flutter (18652): #9      TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:175:7)
I/flutter (18652): #10     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:315:9)
I/flutter (18652): #11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:73:12)
I/flutter (18652): #12     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:11)
I/flutter (18652): #13     _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:180:19)
I/flutter (18652): #14     _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:158:22)
I/flutter (18652): #15     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:138:7)
I/flutter (18652): #16     _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:101:7)
I/flutter (18652): #17     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:85:7)
I/flutter (18652): #18     _invoke1 (dart:ui/hooks.dart:168:13)
I/flutter (18652): #19     _dispatchPointerDataPacket (dart:ui/hooks.dart:122:5)
I/flutter (18652): 
I/flutter (18652): Handler: onTap
I/flutter (18652): Recognizer:
I/flutter (18652):   TapGestureRecognizer#d5d82(debugOwner: GestureDetector, state: possible, won arena, finalPosition:
I/flutter (18652):   Offset(220.2, 406.1), sent tap down)
I/flutter (18652): ════════════════════════════════════════════════════════════════════════════════════════════════════
W/ActivityThread(18652): handleWindowVisibility: no activity for token android.os.BinderProxy@59b4e8d
I/ViewRootImpl(18652): CPU Rendering VSync enable = true


Solution 1:[1]

This is because the context you are passing into the showDialog method is a context that doesn't yet have a MaterialLocalizations widget in the widget tree, the MaterialLocalizations widget gets added implicitly by the MaterialApp widget.

To fix it, try the following:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Test",
      home: TestPage(),
    );
  }
}

class TestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Test")),
      body: Container(
        child: Center(
          child: RaisedButton(
            color: Colors.redAccent,
            textColor: Colors.white,
            onPressed: () {
              testAlert(context);
            },
            child: Text("PressMe"),
          ),
        ),
      ),
    );
  }

  void testAlert(BuildContext context) {
    var alert = AlertDialog(
      title: Text("Test"),
      content: Text("Done..!"),
    );

    showDialog(
        context: context,
        builder: (BuildContext context) {
          return alert;
        });
  }
}

Solution 2:[2]

An easy fix which worked in my case was simply to move the MaterialApp widget up to the main() method.

main() {
  runApp(MaterialApp(home: App()));
}

Solution 3:[3]

This also happens when you switch to a language that is not supported by the GlobalMaterialLocalizations delegate. It is a tricky message to understand, because it says that you should have the MaterialApp at the top of your tree, but that may already be present.

In my case, the language I was localising (UK Welsh -- cy-GB) is not catered for automatically. I had to write my own delegate for boilerplate strings, and add it to the list of localisations at the root of my app.

The code for the Belarusian delegate is here. I adapted it to cater for the Welsh language. It contains date formatting information, as well as about seventy stock phrases that material design thinks you may need, such as "SELECT ALL", "Page <x> of <y>" etc.

If you need to make a delegate that covers a language not listed in the global material localisations, then once you have created the delegate, look in your codebase, and somewhere near the top of the tree, you will have a line like

MaterialApp(
 localizationsDelegates: [
   GlobalMaterialLocalizations.delegate,
   GlobalWidgetsLocalizations.delegate,
   GlobalCupertinoLocalizations.delegate,
 ],
 supportedLocales: [
    const Locale('en', ''), // English, no country code
    const Locale('he', ''), // Hebrew, no country code
    const Locale.fromSubtags(languageCode: 'zh')
  ],
  // ...
)

Simply add CyMaterialLocalizations.delegate (or whatever you call your new language delegate) to the localizationsDelegates list.

Solution 4:[4]

Adding localizationsDelegates and supportedLocales to MaterialApp solved the issue for me

localizationsDelegates: [
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
      GlobalCupertinoLocalizations.delegate,
    ],

supportedLocales: [
      Locale('en', 'US'),
    ],

Solution 5:[5]

I have the same issue with showTimePicker inside of RaisedButton,

I restructured as:

runApp 
  |__MaterialApp
    |__ StatefulWidget/StatelessWidget
      |__SafeArea
        |__Scaffold
          |__ RaisedButton
            |__ showTimePicker

Here is the sample worked solution:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', 'US'), 
      ],
      home: Sample(),
    ),
  );
}

class Sample extends StatefulWidget {
  @override
  _SampleState createState() => _SampleState();
}

class _SampleState extends State<Sample> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Center(
          child: RaisedButton(
            child: Text('Time Picker'),
            onPressed: () {
              showTimePicker(
                context: context,
                initialTime: TimeOfDay(hour: 10, minute: 47),
                builder: (BuildContext context, Widget child) {
                  return MediaQuery(
                    data: MediaQuery.of(context)
                        .copyWith(alwaysUse24HourFormat: true),
                    child: child,
                  );
                },
              );
            },
          ),
        ),
      ),
    );
  }
}

Solution 6:[6]

Another approach by wrapping the most inner widget that invokes showDialog with Builder. In this scenario, the most inner widget is TextButton (note that I replaced the deprecated RaisedButton with TextButton).

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Test")),
        body: Container(
          child: Builder(
            builder: (context) {
              return TextButton(
                child: const Text('Show'),
                onPressed: () {
                  showDialog(
                    context: context,
                    builder: (_) => AlertDialog(
                      title: Text("Test"),
                      content: Text("Done..!"),
                    ),
                  );
                },
              );
            },
          ),
        ),
      ),
    );
  }
}

Solution 7:[7]

I faced the same issue, where I need to show dailog in

initState();

which I solved like this,

Future.delayed(Duration.zero, () {
  showGameOverDailog(context);
});

Solution 8:[8]

In my case it occurred when I passed to insert this record in StatefulWidget:

const MyApp({Key? key}) : super(key: key);

Solution 9:[9]

Build method should return MaterialApp and NOT Scaffold. Within home of your Material App you can have Scaffold

Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(),   //or your Page with Scaffold
    );
  }