Align widget in bottom navigation covers body - flutter

I have a Scaffold with the following architecture, and the body is being covered by the bottom navigation. Everything works fine if I comment the navigation.
Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
appBar: AppAppBar(title: this.title),
body: Row(
children: [
Expanded(
child: Container(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: this.pageProvider.horizontalPadding,
vertical: 25),
child: this.body,
),
),
)
],
),
bottomNavigationBar: AppNavigation(),
);
This is the implementation of the AppNavigation widget:
Stack(
children: <Widget>[
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 64,
child: BottomNavigation(),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 80,
child: WorkoutButton(),
),
),
],
);
This is the body, regardless of what widget I use:
In case it is not clear enough, the body does not have almost height.

Why don’t you use a BottomNavigationBar widget instead of a Stack?
Anyway, that happens because your Stack is unconstrained, thus, using all the available space. Give it some constrains (E.g., by wrapping it in a ConstrainedBox with some height constraint).
ConstrainedBox(
constraints: BoxConstraints.tightFor(height: 150.0),
child: Stack( ...
)
)

Related

How can stretch height of one of child widget according to another widget in a row?

I wanted to get same dynamic height of right widget to left widget in Row Widget.Below I was attaching screenshot of my expected design. Could you help how can do that.
We can see right side date widget is expanding , So I wanted to get the height of left side widget(blue and purple) same as right side widget.
If left side image widget is not possible to expand the height then is any there any possible to create custom widget, Any solution is welcome.
Thanks in advance.
Row(
children: [
Align(
alignment: Alignment.topCenter,
child: Container(
constraints: BoxConstraints(
minHeight: 40.0,
maxHeight: 50.0,
/*maxWidth: 10,
minWidth: 10,*/
),
padding: EdgeInsets.only(top: 0.0),
//height: 98,
width: 20,
child: ShaderMask(
shaderCallback: (bounds) {
return LinearGradient(
colors: [Color(0xff12229F), Color(0xff615FDF)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
).createShader(bounds);
},
child: ImageIcon(
AssetImage('assets/images/reservations/small_timeline.png'),
color: Colors.white,
size: 40,
),
),
),
),
Expanded(
child: Column(
children: [
pickup(data),
dropoff(data),
],
),
),
],
),
After Using IntrinsicHeight
I was unable to remove default padding around the icons
IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.only(top: 0,bottom: 0),
child: Row(
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 4),
child: Icon(
Icons.fiber_manual_record,
size: 18,
color: Color(0xff11219E),),
),
Flexible(
child: Container(
decoration: BoxDecoration(
gradient:
LinearGradient(colors: [Color(0xff11219E), Color(0xff6F6AEB)]),
),
width: 4,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Icon(
Icons.fiber_manual_record,
size: 18,
color: Color(0xff6F6AEB),),
),
],
),
Expanded(
child: Column(
children: [
pickup(data),
dropoff(data),
],
),
),
],
),
),
),
It seems to me that Expanded could be used to expand your widget to full availabe height.
Keep in mind that the Row width will distribution will also expand, since no flex parameter is provided.
You already have an Expanded on the right widget so just add the other one and provide a flex value for both of them.
Some thing like 10 for left and 90 for right should work for you :)

Flutter: Expanded overriding ConstrainedBox

I need a Column to expand to a constrained width. So it expands until the maxWidth but doesn't mind being smaller if there isn't enough space. But the Expanded ignores the ConstrainedBox.
Row(
children: [
const Spacer(),
Expanded(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 50),
child: Column(
children: [
Expanded(child: Container(color: Colors.red)),
Expanded(child: Container(color: Colors.green)),
],
),
),
),
],
)
Here's my full code for context:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: GetBuilder<TimerController>(
builder: (_) => CustomBackground(
color: _timerController.currentChild?.color ?? Colors.blue,
child: SafeArea(
child: Center(
child: Padding(
padding:
EdgeInsets.symmetric(horizontal: AppSizes.pagePadding),
child: OrientationBuilder(
builder: (context, orientation) =>
(orientation == Orientation.portrait)
? ConstrainedBox(
constraints: BoxConstraints(
maxWidth: AppSizes.maxWidth,
minWidth: AppSizes.minWidth,
),
child: Column(
children: [
SizedBox(height: AppSizes.pagePadding),
Expanded(child: TimerClock()),
Expanded(
child: Column(
children: [
NameText(),
ControlButtons(),
SizedBox(height: 25),
Expanded(child: QueueList()),
],
),
),
],
),
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: AppSizes.maxWidth,
minWidth: AppSizes.minWidth,
),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: AppSizes.pagePadding),
child: TimerClock(),
),
),
),
SizedBox(width: AppSizes.pagePadding),
Expanded(
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: AppSizes.maxWidth, // this get's ignored
minWidth: AppSizes.minWidth,
),
child: Column(
children: [
Expanded(child: NameText()),
ControlButtons(),
SizedBox(height: 25),
Expanded(child: QueueList()),
],
),
),
),
],
),
),
),
),
),
),
),
),
);
}
And if I remove the Expanded, the Column has a fixed width (maxWidth) and throws an error if there isn't enough space.
Change the outer most Expanded to a Flexible. Then the child ConstrainedBox will be respected.
In my case I also added a width:double.infinity to the child of the Flexible to force the widget to always be as big as the maxWidth, and only reduce its size when there is no space.
My example:
Flexible(
child: Container(
constraints: BoxConstraints(maxWidth: screenWidth * 0.25),
width: double.infinity,
),
);
You are using Expanded in a Column widget which means that it will try to expand to fill the space vertically (based on the height of the parent not its width). As mentioned in the documentation of Expanded:
Using an Expanded widget makes a child of a Row, Column, or Flex
expand to fill the available space along the main axis (e.g.,
horizontally for a Row or vertically for a Column).
source
And as you did not precise a maxHeight in your constraints it will be considered as double.infinity.

Flexible scrolling content on overflow

I want to have a container with a flexible body (red) height and a fixed button height (gray).
The complete container should be as small as possible and have a max height.
If the content is overflowing the max height it should be scrollable.
I'm new to flutter, so I have no idea how to achieve this.
I tried it with a ConstraintBox with maxHeight, but then the whole container is bigger then it have to be, when the content is small.
return Container(
child: Column(
children: [
ConstrainedBox(
maxHeight: 400
child: //SomeWidget that could overflow
),
Container(
height: 150,
child: Center(
child: TextButton(child: Text('OK'))
),
)
],
),
);
Can someone help?
You can set constraints of your Container. Also you can use Flexible and SingleChildScrollView
Container(
constraints: BoxConstraints(
maxHeight: 300,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: SingleChildScrollView(
child: Column(
children: [
//SomeWidget that could overflow
],
),
)),
Container(
color: Colors.amber,
height: 150,
child:
Center(child: TextButton(onPressed: () {}, child: Text('OK'))),
)
],
),
)
I've achieved it now, with that code:
Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: SingleChildScrollView(
child: //SomeWidget that could overflow
),
),
Container(
alignment: Alignment.bottomCenter,
child: TextButton(
child: Text('OK')
)
)
]
)
)
According to your UI i think this one will be perfect, and let me know if you need any changes. use constraints to change size.
final widgets = List.generate(
12,
(index) => Container(
height: 100,
color: index % 2 == 0 ? Colors.cyanAccent : Colors.greenAccent,
child: Text("item $index"),
),
);
#override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Stack(
children: [
Align(
alignment: Alignment.topCenter,
child: SizedBox(
///* used 90% of screen for items
height: constraints.maxHeight * .9,
child: ListView(
children: [
Center(child: Text("inside listView")),
///your widgets
...widgets,
Center(child: Text("End of listView")),
],
),
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
color: Colors.grey.withOpacity(.3),
///* used 10% of screen for Button
height: constraints.maxHeight * .1,
child: Center(
child: TextButton(
child: Text('OK'),
onPressed: () {},
),
),
),
),
],
),
),
);
}

Make a column in a ListView/SingleChildScrollView take up the REMAINING space of a screen

I am trying to build a registration screen, the concept that I have designed on adobe XD is that the registration Screen will have the app logo in the top center, a card with approximately 3-4 textfields/areas, a button in the bottom center. Since there will be multiple cards to fill I want a circular page indicator in the center to make it easier for the user to track the remaining data to fill as well as the user wont have to fill a really long list in a single screen.
What I have tried is
A SingleChildScrollView with a column inside it and the column has the first registration form to fill and another column inside it that has the button with the page indicator
A Stack and a pageviewbuilder this gave me the best results in terms of layout but the only issue is that when using the keyboard the widgets will throw a renderFlew overflow
and right now a listview with the form in it and a column that has the button and the page indicator
Things that I need:
the keyboard to not cause an issue with form
the code to be practical and consistent for multiple screen sizes
my latest code
#override
Widget build(BuildContext context) {
List<Widget> registrationForms = [EmailRegistrationForm()];
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: ListView(
children: <Widget>[
Align(alignment: Alignment.center, child: registrationForms[0]),
Container(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 5),
child: InkWell(
child: Text("Already have an account? Login!"),
),
),
PrimaryStyledButton(text: "Next", onPress: () {}),
CirclePageIndicator(
currentPageNotifier: _currentPageNotifier,
itemCount: registrationForms.length,
selectedDotColor: Theme.of(context).accentColor,
)
],
),
),
],
));
}
what is expected
so this is what ended up working for me, I realized that the list view is kinda useless so the structure became as follows:
SingleChildScrollView that has a sized box (size of the screen) and a column inside the sized box, the SingleChildScrollView is to stop the issue of the keyboard pushing things up as well giving the ability to scroll while filling the data
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 10),
child: landingScreen.getLogoWidget(),
),
Expanded(
child: Align(
alignment: Alignment.center, child: registrationForms[0]),
),
Padding(
padding: EdgeInsets.only(bottom: 10),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 5),
child: InkWell(
child: Text(ALREADY_REGISTERED_MSG),
),
),
PrimaryStyledButton(text: NEXT, onPress: () {
}, ),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: CirclePageIndicator(
currentPageNotifier: _currentPageNotifier,
itemCount: registrationForms.length,
selectedDotColor: Theme.of(context).accentColor,
),
)
],
),
),
],
),
),
));
Try using SingleChildScrollView with expanded widget
#override
Widget build(BuildContext context) {
List<Widget> registrationForms = [EmailRegistrationForm()];
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: SingleChildScrollView(
child: Expanded(
child: Column(
children: <Widget>[
Align(alignment: Alignment.center, child: registrationForms[0]),
Container(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 5),
child: InkWell(
child: Text("Already have an account? Login!"),
),
),
PrimaryStyledButton(text: "Next", onPress: () {}),
CirclePageIndicator(
currentPageNotifier: _currentPageNotifier,
itemCount: registrationForms.length,
selectedDotColor: Theme.of(context).accentColor,
)
],
),
),
],
),
),
),
);
}

Flutter using wrap_content for TabBarView

in this below code i have Wrap widget into TabBarView and i'm not sure as this widget size, when i use Container with specify height my problem solved, but i miss some layouts which i want to show that with map, how can i resolve this problem? i tested SizedBox.expand but it doesn't any change
Flexible(
child: TabBarView(
children: [
Center(
child: Wrap(
children: feeds.map((feed){
return Container(
width: MediaQuery.of(context).size.width /3.5,
height:MediaQuery.of(context).size.width /3.5,
margin: EdgeInsets.all(2.0),
child: GridTile(
header: feed.feedType ==1?Icon(Icons.video_call)
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(3.0)
child: Image.asset(feed.feedImage))),
),
);
}).toList(),
),
),
],
controller: tabController,
),
),