How to scroll horizontally InteractiveViewer with overflowed widgets - flutter

So I am pretty new to flutter. I am trying to replicate app that I have already made using only Android Views and Java.
So what I am trying to do is create stack of hidable/showable map layers (roads, marks, etc.). I want it to be zoomable and expanded to the height of the screen. Layers are 1:1 so it will overflow the screen width. That is intended.
So I found out that InteractiveViewer allows me to zoom. As a child I created Stack (with StackFit.expand parameter) of SvgPicture.assets (I am using svg files). Problem is, the InteractiveViewer allows me to zoom only the visible part of the Stack and do not allow me to scroll horizontally to the edges of the Stack.
What should I change to be able to zoom it correctly or scroll to the edges? I was trying to play with SingleChildScrollView, OverflowBox or InteractiveViewer's isConstrained parameter, but no success. Most of the times, the Stack of layers just disappeared. I'm willing to drop the zooming for at least scrolling to left and right. I was playing with SingleChildScrollView that wrapped Stack but no success either.
In the picture below there is a sketch of what it looks like. Orange part is header, rectangle with red border is the overflowed Stack with layers and rectangle with blue border is the area I can zoom within.
Image:
Code is here:
Container(
color: Color(Values.colorBodyMap),
alignment: Alignment.center,
child: Column(mainAxisSize: MainAxisSize.max, children: [
Row(mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.max, children: [
Expanded(
child: Container(
height: 70,
alignment: Alignment.center,
child: AutoSizeText( ... )
)
)
]),
Expanded(
flex: 1,
child: InteractiveViewer(
child: Stack(
fit: StackFit.expand,
children: [for ( ... ) SvgPicture.asset(s, fit: BoxFit.fitHeight)],
)))
]))

Related

Flutter Stack: how to place items at the bottom

I have the following widget StackedIcons
reuturn Container(
color: Colors.green,
child: Stack(
clipBehavior: Clip.none,
children: [
CircleAvatar(), Positioned(left: 15, child: PlusOne())
]),
);
which I want right aligned inside another widget
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [StackedIcons(match: match)]
)
and this is what I get
This looks good in terms of what I want to achieve (the plus one on top of the user avatar). However it overflows the parent container.
If I use right offset for positioned the order of the icons will be inverted and I don't want that.
If possible I would like to specify to Stack place the element below the current one (rather than on top).
The output I want is to have this widget rigth aligned without going over the padding of the parent. If I remove the Clip.none behaviour I get
A possible solution might be to place your PlusOne inside the green Container, and then give the Avatar some offset on the right instead.
return Container(
color: Colors.green,
child: Stack(
clipBehavior: Clip.none,
children: [
Positioned(right: 15, child: CircleAvatar()),
PlusOne(),
]),
);
I'm not sure how this would affect things if you were to have multiple avatars and then the plus icon, but if you haven't tried this, it might work for you.

Flutter position row at bottom of screen inside a SingleChildScrollView?

I have a screen with a graph and some buttons and then some nav buttons...
in portrait, everything fits on the screen, but I want the nav buttons to be at the bottom of the screen, and the graph to be at the top of the screen
in landscape-phone, there's not enough room...
So I put the whole thing into a SingleChildScrollView(child:column(child: [stuff, navbuttons]), but that resulted in everything being close together and centered.
I tried SingleChildScrollView(child:column(child: [stuff, Spacer, navbuttons]), but that makes a RenderFlex children have non-zero flex but incoming height constraints are unbounded error.
What's the way to make a "SpacerBigEnough" class?
I've accomplished similar UI by using a CustomScrollView, like so:
CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Column(
children: [stuff],
),
),
SliverFillRemaining(
hasScrollBody: false,
child: Align(
alignment: Alignment.bottomCenter,
child: navbuttons,
),
)
],
)

Flutter SingleChildScrollView with Expanded

How do you guys solve the following Flutter layout??
I have a screen, where I have to show, as described in the picture: a logo + 3 TextFormFields + 2 buttons + a Container.
Problems:
I need to put all the widgets inside a Column and, the Column inside a SingleChildScrollView so that, when the keyboard pops up, it does not cover the TextFields.
The last widget, the Container, shall take all the remaining screen space on the bottom, but NOT taking more than the screen size. For that, My idea was to use the Expanded widget, so that the Container can expand to the bottom of the screen, but that gives an error:
The following assertion was thrown during performLayout(): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
So I guess my question, in short is, how do I prevent the keyboard to cover the TextFields, while at the same time I force the Container to take all the remaining space on the bottom.
That was my attempt:
SingleChildScrollView(
child: Column(
children: [
Image.asset("assets/images/appLogo.png"),
TextFormField(),
TextFormField(),
TextFormField(),
Row(children: [TextButton(), TextButton()]),
Expanded(child: Container())
],
));
Expanded doesn't know how much size to take. Also the other children don't know their exact size.
Wrap your Image inside a container and give height & width to it. also try wrapping all textfields inside a column or container each.
SingleChildScrollView(
child: Column(
children: [
Container(
width: MediaQuery.of(context).Size.width * 0.4,
height: MediaQuery.of(context).Size.height * 0.2,
child: Image.asset("assets/images/appLogo.png"),
),
Column(
children: [
TextFormField(),
TextFormField(),
TextFormField(),]
)
Row(children: [TextButton(), TextButton()]),
Expanded(child: Container())
],
));
I hope this will work for you.

flutter - how to align at the top and at the bottom (this is the issue) - and column middle part

I would like to align a container at the bottom of the widget (given there is containers already at the top and some column in the middle)
So far I can align in at the top followed by some containers using Alignment.topCenter and column.
body: Align(
alignment: Alignment.topCenter,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
How can I then put one more container that is right at the bottom of the widget.
reason for this is I want the ad banner to appear at the top and at the bottom. the middle is the real content.
Add Column on top on Align Widget, & add at the bottom of its container with Expanded
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 100, // Give height of banner
color: Colors.green,
),
),
),

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(),
],
),