I'm new to flutter, I have created a multistate toggle button but I want to convert it into dropdown in case the container doesn't have enough space to show the widget. Earlier I was using the LayoutBuilder context width but it is taking the whole width of the page not of the container containing the widget. Can you please help me with this ?
You are using the right approach. LayoutBuilder would work for you, but you should factor the entire widget into its own StateLess widget and use that context to do your measurements.
LayoutBuilder provides a BoxConstraints object with minWidth, maxWidth, minHeight, maxHeight properties that you can use in your code to decide which widget to embed in the tree. The dimension of that BoxConstraints object are calculated from your Widget's immediate ancestor.
Supposed you create MyMultistateToggleBoxOrDropdownWidget() and implement its build method like this:
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// If constraints.maxWidth isn't wide enough,
// return a dropdown Widget,
// otherwise return the multistate toggle box.
}
}
Now that you have a Widget that returns what you want based on width, you need to now wire it into the correct context.
What you're probably missing is that you need to wrap your custom widget inside of something that controls the screen space that you want to present your Widget inside. A SizedBox() will do for this example.
Your solution took the whole page width because that was the width of your Widget's immediate ancestor in the Widget tree.
SizedBox(
width: 100.0,
height: 100.0,
child: MyMultistateToggleBoxOrDropdownWidget()
)
Related
i am searching a way for sizing a element in flutter with the dimensions of the parent widget. How can I do?
I tried with MediaQuery.of(WidgetParent) but this not work.
Thanks
If you want to size the current widget with respect to the parent widget's dimensions, check this Widget FractionallySizedBox
The MediaQuery.of(context) returns the device's screen size, not the parent widget.
You can get the size of the parent widget by using the LayoutBuilder.
YOUTUBE: LayoutBuilder (Flutter Widget of the Week)
LayoutBuilder(
builder: (context, constraints) {
constraints.maxWidth;
...
}
);
This is my simple outline code to generate ListView inside Future builder.
What I wanted to achieve is that I want some widget below of the FutureBuilder widget so I wrapped it with column but the content of future builder got just vanished after adding, but before adding it was fine.
Widget build(BuildContext context) {
child:FutureBuilder(
future: msDB.getListOfMoviesSeries(widget.type,widget.isWatched),
builder: (BuildContextcontext, AsyncSnapshot<List<MovieSeries>> snapshot) {
return ListView.builder(itemBuilder: (context, index) {
return ListTile(
........
)
}
);
}
);
}
Since you are using ListView in Column, The Column has an unbounded height in the vertical axis and your ListView will try to expand to maxHeight and the flutter framework will throw an error. By setting shrinkWrap to true, the extent of the scroll view in the scroll direction is determined by the contents being viewed
So to fix the issue you add following line in your ListView.builder
shrinkWrap:true
You can read more about shrinkWrap here
Hope this helps!
I'm using a SafeArea Widget and want to extract the height of the bottom area which is not within the safe area. As recommended in other sources I tried using MediaQuery.of(context).padding but it always returns EdgeInsets.zero. Is there any other way of getting the size of the bottom region which is not within the safe area?
EDIT:
I had SafeArea widget's bottom property set to true (bottom: true) which always resulted in EdgeInsets.zero. Setting bottom: false returns the actual SafeArea's bottom padding value.
To get Bottom padding use
final bottomPadding = MediaQuery.of(context).padding.bottom;
To get Top padding use
final topPadding = MediaQuery.of(context).padding.top;
If you want to get height of App Bar which is used as flutter Material component
AppBar appBar = new AppBar();
appBar.preferredSize.height;
To get only Safe Area's height, try to access MediaQuery somewhere before adding SafeArea in the widget tree. This way you will get MediaQuery.of(context).padding with some value instead of EdgeInsets.zero. Padding is set to zero after insertion of SafeArea in the widget tree.
Doc for the child of SafeArea Widget says
The padding on the MediaQuery for the child will be suitably adjusted
to zero out any sides that were avoided by this widget.
So to get height excluding the height of all the system layers, try -
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final padding = MediaQuery.of(context).padding;
final heigth = size.height - padding.top - padding.bottom;
return SafeArea(
...
);
}
import 'dart:ui' as ui;
MediaQueryData.fromWindow(ui.window).size;
MediaQueryData.fromWindow(ui.window).padding;
SafeArea widget's bottom ant top properties buy default are set to true.
Setting 'bottom: false' and 'top: false' returns the actual SafeArea's bottom and top padding value.
return SafeArea(
top: false,
bottom: false,
child: Scaffold(
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
...
To get the size/position of a widget on screen, I can use GlobalKey to get its BuildContext and then find the RenderBox.
But for ErrorWidget(Red Screen) when build() error happened I want to calculate the error area's size, and then decide whether to destroy the page or replace with other widget e.g. Container().
I have already used ErrorWidget.builder create custom ErrorWidget, but need to be more precise, different sizes of ErrorWidget are treated differently. How to get ErrorWidget size for rebuild?
ErrorWidget do not evade the widgets rules.
A widget cannot depend on the size of anything else.
You can, however, use LayoutBuilder to calculate the available size.
LayoutBuilder Widget can help us know how much space is available for the child widget, before finally build it. It's builder function has parameters BuildContext context, BoxConstraints constraints.
BoxConstraints constraints provides us with the opportunity to execute custom logic.
ErrorWidget.builder = (FlutterErrorDetails details) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
Size screenSize = MediaQuery.of(context).size;
double screenRatio = (constraints.maxWidth * constraints.maxHeight) /
(screenSize.width * screenSize.height);
if (screenRatio < ACCEPTABLE_SCREEN_RATIO) {
return Container();
}
return ErrorWidget(details.exception);
},
);
};
I have an Expanded Widget with an Image.asset(...) as it's child.
On small phones there is not enough space and the image is scaled down massively. Since it is only for eye-candy anyways, I'd like to hide / not show the Image if there isn't at least a height >= 100.0 available.
How do I accomplish this in Flutter? Is there a way to get the parent widgets size?
You can use LayoutBuilder to obtain the input constraints of a widget.
Then based on these constraints decide to display or not an image
LayoutBuilder(
builder: (context, constraint) {
if (constraint.maxHeight < 100.0) {
// too small
return Container();
} else {
// ok
return Column(
children: <Widget>[
Image.asset("foo"),
Container()
],
);
}
},
)
Awesome Remi's solution, and You can use the MediaQuery and MediaQueryData too, has some properties and methods that can help your in situations like that.
Some properties are orientation, size, padding, devicePixelRatio, etc.
Example:
MediaQuery.of(context).orientation
https://docs.flutter.io/flutter/widgets/MediaQuery-class.html
https://docs.flutter.io/flutter/widgets/MediaQueryData-class.html