What is the difference between Material and MaterialApp in Flutter? - flutter

I am developing an app using Flutter. If I choose MaterialApp as the parent widget of my app, all Text widgets in my app are underlined yellow. On the other hand, if I just use Material as the parent widget, no yellow lines are shown under the Text widgets.
What is the difference between Material and MaterialApp?

MaterialApp is a widget that introduces many interesting tools such as Navigator or Theme to help you develop your app.
Material is, on the other hand, a widget used to define a UI element respecting Material rules. It defines what elevation is, shape, and stuff. Then reused by many material widgets such as Appbar or Card or FloatingButton.
The yellow underlines you can find in Text is introduced by MaterialApp as a fallback Theme. It is here for debug purpose, to warn you that you need to use Material somewhere above your Text.
In short, use both. You should have a MaterialApp near the root of your app. And then use widgets that introduce a Material instance (Such a Scaffold, Appbar, Dialog, ...) when you want to use Text or InkWell.

MaterialApp : The MaterialApp configures the top-level Navigator to search for routes or to define Home.
Material : For child UI widgets rendering & effects.

Related

MaterialApp builder Method places shadow/gradient around widget

I have a MaterialApp with several routes for the various section of my application.
Description
I have used the builder method of the MaterialApp class to place a single scaffold around all of my routes.
The body of this scaffold is a Row which contains a custom side menu widget, and the Widget from the MaterialApp's builder method.
Problem
Flutter is placing a shadow/gradient between my side menu (the widget from the builder method) and the main body of the application. I do not want this shadow and I do not know how to remove it.
What it looks like at the moment:
What it should look like:
This photo shows the difference between the two results (look at the right hand side of the side menus):
What is the top widget in your routes?
This looks like some default elevation is applied by material. You might (worst case) want to wrap the child within the builder method with a ClipRRect or DecoratedBox with specified clip behaviour to avoid that shadow overlaying your other widgets

Should I always use a SafeArea at the top level of my flutter screens?

I am curious if I should always use a SafeArea widget at the top level of my screen. I mean....when would I want my content blocked by things like a notch? For me it seems like the answer is never.
So should I not just use SafeArea on every page? If so, should it be above or below the Scaffold widget?
You don't have to use SafeArea on every screen. It actually depends if an AppBar is used or not, because the AppBar automatically calculates the values and adds the required padding.
If you use it above a Scaffold the area where the padding is applied would be black. On the other hand, if you use it below the Scaffold the color of the area would depend on the app theme, probably the Scaffold background color.
If you won't add an app bar or add it. if you want to adjust the screen to be responsive using MediaQuery and you don't need any scroll inside the screen use it.
Use it as the first widget in the body of the scaffold.

What's the difference between raisedButton and Container with onTap() (Flutter)?

When we want to achieve a button, we can choose raisedButton in flutter lib, also can a Container with onTap() function. So what's the difference between the two and which one should we choose in different situation?
Container function doesnot have onTap option, but you can achieve it by wrapping it in Guesture detector or Inkwell. There are no changes in the backend. But Raised button gives you the elevation, and animation on tap. You can also do it in the container, but it requires you to manually do it.
If you want a simple button quickly use RaisedButton.
If you want a more complex one, use Container or mixture of Containers, RaisedButton etc.
I am gonna offer something different... A tale of a treasure that is known to have answers to many questions, use cases and sometimes even examples. The name of this treasure is: official documentation. ;)
RaisedButton
A raised button is based on a Material widget whose Material.elevation increases when the button is pressed. Use raised buttons to add dimension to otherwise mostly flat layouts, e.g. in long busy lists of content, or in wide spaces. Avoid using raised buttons on already-raised content such as dialogs or cards.
Container
A convenience widget that combines common painting, positioning, and
sizing widgets.
GestureDetector
A widget that detects gestures. Attempts to recognize gestures that
correspond to its non-null callbacks. If this widget has a child, it
defers to that child for its sizing behavior. If it does not have a
child, it grows to fit the parent instead. By default a
GestureDetector with an invisible child ignores touches; this behavior
can be controlled with behavior. GestureDetector also listens for
accessibility events and maps them to the callbacks. To ignore
accessibility events, set excludeFromSemantics to true. See
flutter.dev/gestures/ for additional information. Material design
applications typically react to touches with ink splash effects. The
InkWell class implements this effect and can be used in place of a
GestureDetector for handling taps.
InkWell
A rectangular area of a Material that responds to touch. For a variant
of this widget that does not clip splashes, see InkResponse... The
InkWell widget must have a Material widget as an ancestor. The
Material widget is where the ink reactions are actually painted. This
matches the material design premise wherein the Material is what is
actually reacting to touches by spreading ink.
Well, technically you are right, they can both react to a click event. But a RaisedButton will have all the styles specific to the target platform taken care of for you (it inherits from MaterialButton).
note that it's the same in html: you can use a regular div with a click handler or use a button tag. The button will have a few styles already taken care of for you...

Flutter subclass Scaffold so I can ensure a Drawer and BottomNavigationBar are always present

I have a Flutter app with sections that I can access from both a BottomNavigationBar and a Drawer. I have this working in a Scaffold at the root level of my app, and I then use Navigator widgets to create separate routes and stacks within each section. The BottomNavigationBar persists as I push new screens onto the stack, and these new screens will have their own AppBar and actions specific to those user journeys.
The problem is that I need the Drawer to be present on all of my screens, and setting a new AppBar in a Scaffold on individual screens removes the Drawer that I had set in my root level Scaffold.
How can I pass that Drawer through to all my screen AppBar instances? I don't want to create new Drawer instances over multiple widgets, so I should create a Singleton of the Drawer or even the entire Scaffold? What's the best practise here?
You can use a state management package. I suggest use provider packages or flutter_bloc so that you can get more out of flutter UI but be careful about their name and here is a doc link that is made by flutter team and will help you with all the state management package:
https://flutter.dev/docs/development/data-and-backend/state-mgmt/options
This one is for bloc_flutter doc I couldn't find it on the previous link document: https://bloclibrary.dev

Things to be aware of when using a container as a parent instead of MaterialApp/Scaffold

Say I'm building an app that doesn't need Material design elements and use a container as a parent.
Are there things that need to be set up manually (layout-wise) that's unnecessary when using MaterialApp/Scaffold?
Following are few unexpected behaviors I noticed when using a container as a parent:
• Yellow lines in Text widgets (These lines disappear when using Scaffold instead)
• ClipRRect widget takes up the full screen even when I set constraints
Material class is a main component of your UI. Using a Material Widget as parent doesn't mean you are forced to use Material Design for your entire app, you can do your own custom Widgets, UI, etc.
As part of the official documentation:
The Material widget is responsible for:
Clipping: If clipBehavior is not Clip.none, Material clips its widget sub-tree to the shape specified by shape, type, and borderRadius. By default, clipBehavior is Clip.none for performance considerations.
Elevation: Material elevates its widget sub-tree on the Z axis by elevation pixels, and draws the appropriate shadow.
Ink effects: Material shows ink effects implemented by InkFeatures like InkSplash and InkHighlight below its children.
It is also responsible of providing default styles for your Texts (that's why you're seeing the yellow underline).
Still, remember that you're making apps for mobile clients, therefore, you should be using some of the best practices that MaterialApp and CupertinoApp bring out of the box, even if you decide to take your own path inside the app, using your own custom Widgets, etc