user8005219
user8005219

Reputation: 1858

No Material widget found

I am new to Flutter and I was trying do execute the example here. I just want to use the TextField widget to get some user input. The issue is that I get a "No Material widget found." error. What am I doing wrong ? Thank you.

Code:

import 'package:flutter/material.dart';    

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


class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new ExampleWidget(),
    );
  }
}


/// Opens an [AlertDialog] showing what the user typed.
class ExampleWidget extends StatefulWidget {
  ExampleWidget({Key key}) : super(key: key);

  @override
  _ExampleWidgetState createState() => new _ExampleWidgetState();
}

/// State for [ExampleWidget] widgets.
class _ExampleWidgetState extends State<ExampleWidget> {
  final TextEditingController _controller = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return new Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        new TextField(
          controller: _controller,
          decoration: new InputDecoration(
            hintText: 'Type something',
          ),
        ),
        new RaisedButton(
          onPressed: () {
            showDialog(
              context: context,
              child: new AlertDialog(
                title: new Text('What you typed'),
                content: new Text(_controller.text),
              ),
            );
          },
          child: new Text('DONE'),
        ),
      ],
    );
  }
}

This is the error stack:

Launching lib/main.dart on Android SDK built for x86 in debug mode...
Built build/app/outputs/apk/app-debug.apk (21.5MB).
I/flutter ( 5187): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 5187): The following assertion was thrown building InputDecorator(decoration: InputDecoration(hintText:
I/flutter ( 5187): "Type something"); baseStyle: null; isFocused: false; isEmpty: true; dirty):
I/flutter ( 5187): No Material widget found.
I/flutter ( 5187): InputDecorator widgets require a Material widget ancestor.
I/flutter ( 5187): In material design, most widgets are conceptually "printed" on a sheet of material. In Flutter's
I/flutter ( 5187): material library, that material is represented by the Material widget. It is the Material widget
I/flutter ( 5187): that renders ink splashes, for instance. Because of this, many material library widgets require that
I/flutter ( 5187): there be a Material widget in the tree above them.
I/flutter ( 5187): To introduce a Material widget, you can either directly include one, or use a widget that contains
I/flutter ( 5187): Material itself, such as a Card, Dialog, Drawer, or Scaffold.
I/flutter ( 5187): The specific widget that could not find a Material ancestor was:
I/flutter ( 5187):   InputDecorator(decoration: InputDecoration(hintText: "Type something"); baseStyle: null;
I/flutter ( 5187):   isFocused: false; isEmpty: true)
I/flutter ( 5187): The ownership chain for the affected widget is:
I/flutter ( 5187):   InputDecorator ← AnimatedBuilder ← Listener ← _GestureSemantics ← RawGestureDetector ←
I/flutter ( 5187):   GestureDetector ← TextField ← Column ← ExampleWidget ← _ModalScopeStatus ← ⋯
I/flutter ( 5187): 
I/flutter ( 5187): When the exception was thrown, this was the stack:
I/flutter ( 5187): #0      debugCheckHasMaterial.<anonymous closure> (package:flutter/src/material/debug.dart:26)
I/flutter ( 5187): #2      debugCheckHasMaterial (package:flutter/src/material/debug.dart:23)
I/flutter ( 5187): #3      InputDecorator.build (package:flutter/src/material/input_decorator.dart:334)
... <output omitted>
I/flutter ( 5187): (elided one frame from class _AssertionError)
I/flutter ( 5187): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter ( 5187): Another exception was thrown: No Material widget found.

Upvotes: 173

Views: 168614

Answers (11)

Milan Makwana
Milan Makwana

Reputation: 33

I used below approach while using hero animation widget.

    @override
  Widget build(BuildContext context) {
    bool isKeyboardShowing = MediaQuery.of(context).viewInsets.vertical > 0;
    return Scaffold(
        resizeToAvoidBottomInset: false,
        body: Hero(
          tag: AppStrings.imageSignIn,
          child: Material(
            child: Container()),

Personal Recommendation : Not use Hero widget above the scaffold because it stays in widget tree and it will throw exception while showing any snackbar on the screen. Thanks.

Upvotes: 2

max
max

Reputation: 59

Wrap your Column with Scaffold or Material

Upvotes: 5

Ruble
Ruble

Reputation: 4824

Try this method: simply add the line builder to MaterialApp:

builder: (context, child) => Material(child: child),

Here you can also provide a typical page with AppBar, Body, ScrollConfiguration, Platform and other elements as you wish (you can even add global listeners). It's just very convenient :) And any page along the route will be wrapped.

For example, from the BuildContext passed to this method, the Directionality, Localizations, DefaultTextStyle, MediaQuery, etc, are all available. They can also be overridden in a way that impacts all the routes in the Navigator or Router.

This is rarely useful, but can be used in applications that wish to override those defaults, e.g. to force the application into right-to-left mode despite being in English, or to override the MediaQuery metrics (e.g. to leave a gap for advertisements shown by a plugin from OEM code).

Upvotes: 1

saigopi.me
saigopi.me

Reputation: 14908

Instead of InkWell use GestureDetector widget, for me fixed issue.

Upvotes: 5

saigopi.me
saigopi.me

Reputation: 14908

Just Wrap your Widegt with Material widget, it fixes the problem.

Material(
  child: InkWell(
    onTap: onPressed,));

Upvotes: 41

Fabio Ambrozio
Fabio Ambrozio

Reputation: 70

This can be caused by wrong routes.

Check your routes one by one. enter image description here

Upvotes: 1

Mahesh Jamdade
Mahesh Jamdade

Reputation: 20221

In my case, I was using a hero widget Inside a scaffold-like this

Scaffold(
  body:Hero(
    child:ListView(
      children:<Widget>[
        TextField(),
           ...
           ...
      ]
    )
  )
);

I simply moved the Hero Widget Outside Scaffold and it solved the problem

Hero(
  child:Scaffold(
    body:ListView(
      children:<Widget>[
        TextField(),
        ...
        ...
      ]
    )
  )
);

Upvotes: 18

Maureen Josephine
Maureen Josephine

Reputation: 516

The error means you have to wrap the column inside a Material widget, you could place it as a body to the scaffold or place it as a home to Materialapp. for instance:

 return MaterialApp(
   home: Column(
     mainAxisAlignment: MainAxisAlignment.center,
     children: [
       TextField(
         controller: _controller,
         decoration: new InputDecoration(hintText: 'Type something'),
       ),
     ]
   ),
 );

or

return MaterialApp(
   body: Column(
     mainAxisAlignment: MainAxisAlignment.center,
     children: [
       TextField(
         controller: _controller,
         decoration: new InputDecoration(hintText: 'Type something'),
       ),
     ]
   ),
 );

Upvotes: 4

live-love
live-love

Reputation: 52366

Put your widget inside a Scaffold, like this:

    import 'package:flutter/material.dart';

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

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Demo',
          //home: MyWidget(), --> do not do this !!!
          home: Home() --> this will wrap it in Scaffold
        );
      }
    }

    class Home extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text('Demo'),
            ),
            body: MyWidget()); --> put your widget here
      }
    }

class MyWidget extends StatefulWidget {
...

Upvotes: 6

Jo&#227;o Rodrigues
Jo&#227;o Rodrigues

Reputation: 794

The easy fix is:

Instead of using:

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

You should use:

void main() => runApp(
  MaterialApp(
    home: MyApp()
  )
);

Hope this helps you!

Upvotes: -9

Collin Jackson
Collin Jackson

Reputation: 116728

The error message says:

To introduce a Material widget, you can either directly include one, or use a widget that contains Material itself, such as a Card, Dialog, Drawer, or Scaffold.

In your case, I'd probably wrap your Column in a Scaffold. This will make it easy to add other material widgets to your app later, such as an AppBar, Drawer, or FloatingActionButton.

@override
Widget build(BuildContext context) {
  return new Scaffold(
    body: new Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        new TextField(
            controller: _controller,
            decoration: new InputDecoration(
                hintText: 'Type something',
            ),
        ),
        new RaisedButton(
            onPressed: () {
              showDialog(
                  context: context,
                  child: new AlertDialog(
                      title: new Text('What you typed'),
                      content: new Text(_controller.text),
                  ),
              );
            },
            child: new Text('DONE'),
        ),
      ],
    ),
  );
}

Upvotes: 234

Related Questions