Can (should?) Stack expand its size to its positioned children? - flutter

I have a Stack widget that contains two Image widgets, one image overlaying the other. One image has top set to 10 so it sits 10 pixels higher on the screen. Unfortunately the 10.0px gets cut off at the bottom of the screen. If I set an overflow.visible then I can see it.
I wrap the stack with a GestureDetector the 10.0px overflow is not inside the GestureDetector so when a user clicks on the bottom of the image, nothing happens. The images will be different sizes so I can't set a definite height.
Is there a way to increase the size of the GestureDector to the size of its children?
return new GestureDetector(
onTapDown: (x) => print('onTapDown'),
child: new Stack(
overflow: Overflow.visible,
children: [
new Positioned(
child: shadowImage,
top: 10.0,
),
new Positioned(
child: initialImage,
),
],
),
);

Can (should?) Stack expand its size to its positioned children?
No. But if you want the following, then your child should not be positionned.
Stack, if it has one, will size itself around the first non-positionned child.
So you could transform your shadowImage to
children: [
new Padding(
padding: const EdgeInsets.only(top: 10.0),
child: shadowImage
),
new Positioned(
child: initialImage,
),
],

Related

Display arrow indicator if list is scrollable

I have an horizontal SingleChildScrollView widget with variable amount of different buttons. I want to display button with right arrow only when there is too much buttons to show all on screen. I want to avoid situation when someone could dont know about more buttons hidden behind right edge of the screen.
How to achieve this?
Container(
height: iconsBarHeight,
color: Theme.of(context).scaffoldBackgroundColor,
padding: const EdgeInsets.fromLTRB(16, 16, 8, 0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Button2(),
Button4(),
Button1(),
Button6(),
Button7(),
Button3(),
Button2(),
],
),
),
);
you can add ScrollControlller to SingleChildScrollView, and get the max extent of it. If max extent is greater than width of screen, then show the button.
scrollController.position.maxScrollExtent

Flutter: how to create widget positioned relative to the screen?

Basically I need to create some kind of Snackbar widget that can be created on any page. So I need to make it positioned relative to the screen. The only idea is to create the main Stack widget which will wrap all other pages. Do you have any other ideas? I found pretty similar question without any interesting answers
By using Mediaqueryto retrieve the screen size.
For example we can the screen width like this :
MediaQueryData screenSize = MediaQuery.of(context).size.width;
let's say i want my container's size to take up half the screen's size
One way to go about it is like this :
Container(
height: MediaQuery.of(context).size.height/2,
width: MediaQuery.of(context).size.width/2,
child: Text('This container is half this device screen's size');
);
What you are going for here is using the Positioned widget
Let's take the last example and leave a quarter of the screen on every side :
Container(
height: MediaQuery.of(context).size.height/2,
width: MediaQuery.of(context).size.width/2,
child: child: Stack(
children: <Widget>[
Positioned(
left: MediaQuery.of(context).size.width/4,
top: MediaQuery.of(context).size.height/4,
right: MediaQuery.of(context).size.width/4,
bottom: MediaQuery.of(context).size.height/4,
child: Text('This container is half this device screen's size'),
),
],
),

Flutter: how to center a child, but set a limit on how big it can grow on one side of the margin

I have a home/login screen which is made up of a column that fills the entire screen like so:
Column(
children: <Widget>[
Expanded(
child: Container(
child: Logo(),
),
),
showThis ? This() : That(),
],
),
The second child of the column is dynamic and can have different heights, and this screen will have inputs so the keyboard will also affect the height.
I want to center Logo() vertically within the container when it's small (e.g. when keyboard is active), but limit how much the 'top margin' is able to grow, so that when the keyboard is hidden and This()/That() is small enough, Logo() will be in a static position on the screen, say 150 from the top (no longer centred vertically).
One method I have tried was using 2 empty Expanded() above and below Logo() and wrapping the top part in a ConstraintedBox(), but I am not able to get it to behave correctly.
Have you tried with Center() and also if you wanna in a specific position use Stack, for example
Stack(
children: <Widget>[
showThis(),
Positioned(top: 150, child: Logo())
],
)
This is what ended up working for me:
Column(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
// constrain top spacing with a max height
Flexible(child: Container(height: 160)),
_logo(),
Spacer(),
],
),
),
_bottomWidget(),
],
),

How to make a InkWell/GestureDetector clickable when they are overflowing parent?

I have a Stack inside a Container with fixed size. The Stack has Positioned children with InkWell children inside. If I push a child to the left with e.g. left: -15, the InkWell is still visible outside the Container, however not clickable anymore outside of the Container.
Here the simplified version of the code:
Container(
width: 300,
height: 100,
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
top: 0,
bottom: 0,
left: -15,
child: InkWell(
onTap: () {},
child: Padding(
padding: EdgeInsets.all(15.0),
child: Text("Test"),
),
),
),
],
),
);
I am trying to make the overflowing part (the 15 pixels to the left) of the InkWell clickable too. Right now I can only click everything inside the container.
The reason I am doing this is to make buttons easier clickable, while not moving the visible text to a different location.
Sadly:
It is intentional that widgets in the overflow area of a stack do not react to gestures and that's unlikely to change. I recommend that people with this (or similar) problems refactor their app to keep all interactable elements within the bounds of a stack.
source: https://github.com/flutter/flutter/issues/19445
In short, don't use overflow. Refactor your layout to make sure it's well contained inside the bounds of its parent.

Flutter material button with unwanted padding/additional width

I can't figure out what's giving this button extra width/padding. The image used is cropped so has no spacing to the left or right and you can see in the attached screenshot from the dev tools that it doesn't occupy the width. Somehow the button has extra width but I don't know where it's coming from.
I have another identical button next to it and with the added space it's causing overflow.
Changing the image size with the width parameter doesn't affect the amount of space the material button takes up either. It seems to be a fixed size.
This is the whole code:
Scaffold(
body: Row(
children: <Widget>[
MaterialButton(
child: Image.asset("images/male.png", width: 33)
)
],
),
);
I also tried other buttons like FlatButton and RaisedButton but they are the same with this additional width/padding. I also tried setting padding with on the button to EdgeInsets.all(0) but that doesn't change anything either.
The extra space is from the minWidth default value which is taken from the current ButtonTheme (you can see that from the MaterialButton source code). You can remove the extra space by adding minWidth to 0 and padding to 0 to your MaterialButton widget. Something like this:
Scaffold(
body: Row(
children: <Widget>[
MaterialButton(
padding: EdgeInsets.all(0),
minWidth: 0,
child: Image.asset("images/male.png", width: 33),
)
],
),
);
Use a container, where you can specify the width
Scaffold(
body: Row(
children: <Widget>[
new Container(
width: 33,
child : MaterialButton(
child: Image.asset("images/male.png")
),
],
),
);