What is the difference between child and body properties in flutter - flutter

I am new to flutter. I followed a tutorial in which they demonstrated two widgets: a Scaffold and a FloatingActionButton.
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.deepOrange,
child: Icon(Icons.add, color: Colors.black),
)
Here we are using the child property to specify the icon.
body: Text("Hello world"),
Here we are using body inside the Scaffold.
What is the difference between child and body and where do we use them?

What is the difference between child and body and where do we use
them?
They are just different names.
Most widgets in flutter use child or children to represent the Widget that should be rendered below the widget in the WidgetTree, but in the case of Scaffold the property is named body, to make it clear that the body widget will be rendered as the body or the largest part of the screen in the app as Scaffold also accepts appBar, floating action button, etc.
What's important here is that whether body or child they are both of type Widget

Related

Static Widgets with a PageView

Is there a way to make a few widgets static upon a PageView change?
I know I can make one widget static by wrapping the Scaffold within a Container, and have that Container have something like a decoration, but I don't know how to add more widgets that do not change when a page changes.
I have a few widgets that change when the page view changes, but then I want to have, say a Button below those widgets that stay still, but
if I put the same Button in every widget, it will swipe through and show two buttons when I change the page momentarily.
I just figured it out, I thought the PageView can only be assigned to the body property of a Scaffold, but wrapping it within a Column like this works. So just add the static widgets within the Column!
return Container(
decoration: BoxDecoration(), // For background.
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Column(
children: [
Flexible(child: pageView),
// Static Widgets here!
],
),
),
);

Flutter - Bottom Overflowed Issue when Keyboard is Presented

I have a view that contains a Column of Widgets. One of the Widgets contains a button that will open a bottom sheet. Within that bottom sheet, a user can tap a TextField and open the keyboard which will keep the bottom sheet above the keyboard.
When I do this as-is, I get Bottom Overflowed by XXX Pixels. The yellow box is behind my bottom sheet, right above the keyboard.
I have tried wrapping the Column in a SingleChildScrollView but when I do that all of the Widgets in my Column disappear.
I have also tried wrapping in a Scaffold & that did not work either:
example:
Scaffold(
resizeToAvoidBottomInset: false, // tried setting to true as well
body: Column...
Any suggestions?
Here's some of the base setup:
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildWidget1(),
_buildWidget2(),
_buildWidget3(),
// When wrapped in a SingleChildScrollView
// this seems to be making everything in the column
// disappear...
Expanded(child: Container()),
etc.
],
);
}
void _bottomSheetButtonPressed(context) {
showModalBottomSheet(
barrierColor: Colors.transparent,
backgroundColor: Colors.transparent,
context: context,
isScrollControlled: true,
builder: (context) {
return Padding(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(24),
topRight: const Radius.circular(24),
),
),
child: _showBottomSheetItemsWidget(),
),
);
},
);
}
The colors are transparent just so I can see what is happening behind the bottom sheet.
So, with this I am getting the Bottom Overflowed issue... and that is what I am trying to resolve.
Update:
After further debugging, I do see what I believe is making all my Widgets disappear. I have an Expanded Widget that has a child of Container to separate some of my Widgets.
The correct solution is indeed to wrap what you see into a scrollable widget such as SingleChildScrollView. But this can happen if and only if the contents of your scrollable widgets aren't infinite.
Indeed, the reason your widget simply "disappear" is an internal widget that forces infinite height (in this case, the Expanded widget), while the parent do not force a maximum height (the SingleChildScrollView), since it expects any number of widgets to be displayed. This causes an intrinsic / conceptual error (if you think about it) and therefore the framework throws an error.
It kinda depends on what you want to achieve, but as a rule of thumb in cases like this chances are that you want to wrap your scrollable widgets inside a SizedBox / Container / ConstrainedBox, so that you specify a height and therefore you force it to be not infinite.
In that case, your child widgets can use the Expanded logic with no issues.
Let me know if that helps.

how to give text style to a widget and have the same applied for all its descendents in flutter?

Let's say I have a custom widget that I accept as a parameter to be used inside my widget , I want to style all the text inside that widget to a specific font colour.
How do I do this ? I don't want to change the theme of the whole app.
I just want to set the style for the text inside that custom widget.
How to give text style to a widget and have the same applied for all its descendants ?
DefaultTextStyle Could best solution for changing text style for specific widget tree.
DefaultTextStyle(
style: TextStyle(
color: Colors.red,
),
child: Text("data"),
),

How to make Hero animation for two widgets

I need to make animation like Hero in two different widgets. Is that possible?
Widget a with image a and widget b with image a but widget a is inside a listview and widget b is full screen image(it hide listview)
It's very simple. You just need to wrap both widgets in a Hero widget using the same TAG property value. The snippet below is assuming you've a Image in a ListTile and after user clicks you show a new page with the same image but that image will be animated by Hero widget.
In list page the list items can be
ListTile(
leading: Hero(
tag: IMAGE_TAG, // must be the same in different pages
child: Image(image: AssetImage('you_asset_dir/yourImage.png')),
),
title: Text('Anything'),
onTap: () => // Just go to full screen page
);
In full screen page
Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Hero(
tag: 'IMAGE_TAG', // must be the SAME VALUE DEFINED IN list tile hero child widget.
child: Image(image: AssetImage('you_asset_dir/yourImage.png')),
),
),
);
OBS: The Hero tag property must be the same in different contexts but if you have a list with many items using Hero widget each Hero int the same context/page must have different tag values.
To deep dive concepts about Hero animations check the official doc

Flutter error - The specific widget that could not find a Material ancestor was:

I am using the Align widget to place an Icon button at the bottom center of the screen.
However, I get the following error and I'm unable to resolve it:
The specific widget that could not find a Material ancestor was:
IconButton
My code:
return Stack(
children: <Widget>[
Container(
child: GoogleMap(
initialCameraPosition:
CameraPosition(target: LatLng(1,1), zoom: 15),
onMapCreated: (map) {
mapReady;
},),
),
Align(
alignment:Alignment.bottomCenter,
child: IconButton(
icon: Icon(Icons.next_week), onPressed: (){}),
)
],
If I replace the IconButton widget with for example a Text widget it works well.
Could you please explain why it doesn't work, why the IconButton needs a Material ancestor?
Because as per documentation of IconButton (https://api.flutter.dev/flutter/material/IconButton-class.html)
An icon button is a picture printed on a Material widget that reacts
to touches by filling with color (ink).
[..]
Requires one of its ancestors to be a Material widget.
IconButton uses most likely ThemeData as well as other things which MaterialApp normally provides.
Is there a reason you dont use MaterialApp as ancestor?
If you wrap you stack (or the parent in general) with Scaffold you will n get this error.
In this case, if you wrap your IconButton with Material Widget,i believe it will fix the problem:
Align(
alignment: Alignment.bottomCenter,
child: Material(
child: IconButton(icon: Icon(Icons.next_week), onPressed: () {})),
)