How do I align my image to the bottom of my page in flutter? - flutter

I'm trying to set the last image on the bottom of the page. I tried the sized box between this one and the previous image but it changes depending on the device and sometimes it overflows some pixels.
Here is the code:
import 'package:flutter/material.dart';
// ignore: use_key_in_widget_constructors
class LoginPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.amber,
child: Column(
children: <Widget>[
Image.asset("imagens/btop.png"),
SizedBox(
width: 200,
height: 200,
child: Image.asset("imagens/logo.png"),
),
// ignore: prefer_const_constructors
SizedBox(
height: 40,
),
Image.asset("imagens/bbot.png")
],
),
));
}
}

Just use below Widget before your Image widget.
Spacer()

I would use your already existing Column() widget, like this:
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [],
),
Or use Align() in a Stack() or just a Spacer()... there are so many ways to do this, which are all dependent on what you want to do next.
Check out this cheat sheet: https://medium.com/flutter-community/flutter-layout-cheat-sheet-5363348d037e about aligning your widgets and play around with them!

use this :
mainAxisAlignment: MainAxisAlignment.spaceBetween,
inside the Column or in this you having issue then use nested columns

Related

can't figure out where pixels are overlflow even thought I use MediaQuery height

As a demo, I have taken two container inside Column and I have used MediaQuery height for both container and deducting size of appear..eventhought it is showing 24 pixel overflow...and if I wrap column with SingleChildScrollView..it scrolls which should be not scrolled as both container's height sum is 1.
here is my demo code
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final appbar=AppBar();
return Scaffold(
appBar: appbar,
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: (MediaQuery.of(context).size.height-appbar.preferredSize.height)*0.40 ,
color: Colors.green,
),
Container(
height: (MediaQuery.of(context).size.height-appbar.preferredSize.height)*0.60 ,
color: Colors.red,
),
],
),
)
);
}
}
Column has property 'mainAxisSize', setting that to MainAxisSize.min will solve the problem.
Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: (MediaQuery.of(context).size.height-appbar.preferredSize.height)*0.40 ,
color: Colors.green,
),
In this case Column just stretches to infinity as ScrollView above allows it.
I got my answer from stack overflows history ....
here what I missed to deduct status bar height
height: (MediaQuery.of(context).size.height-appbar.preferredSize.height-MediaQuery.of(context).viewPadding.top)*0.60 ,

Scroll Function In Flutter Web

I'm still new to Flutter Web. I have 3 lines in my flutter web, the first line is the welcome message, the second line is a product and the last is contact, to see those lines user needs to do a scroll on my web. But how can I wrap my code using the Scroll function in flutter web? this is my code.
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
body: Column(
children: [
Container(
// Code Line 1
height: size.height,
width: size.width,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/container.jpg"),
fit: BoxFit.fitWidth),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CusAppBar(),
Spacer(),
Body(),
Spacer(
flex: 1,
),
],
),
),
Container(
// Code Line 2 Here
),
Container(
// Code Line 3 Here
)
],
),
);
}
}
My background is react, usually we just use tag ScrollView outside the container so the user can scroll the page. But how I can implement it on flutter web?
Thank you.
Try to add your fist Column inside SingleChildScrollView like below hope it help you:
body: SingleChildScrollView(
child:Column(
children:[
//Declare Your Widgets Here
],
),
),

How to fix a button at bottom of a single child scrollview with a list

I have a SingleChildScrollView and inside it I have a list with some cards, that you can remove ou add more. I need to fix an add button at the bottom of the screen, when the card list is not scrollable yet, but when the card list increase size and the scrollview is able to scroll now (to see all the content), the button must follow the list and not keep fixed at the bottom anymore.
For now, what I did to solve this, was check the scroll view every time that a card is added ou removed, if I checked that the screen is now scrollable or not scrollable I change some properties of my build widget:
SingleChildScrollView(
controller: _scrollController,
physics: AlwaysScrollableScrollPhysics(),
child: Container(
height: isNotScrollable
? _pageSize - (_appBarSize + _notifySize)
: null,
padding: const EdgeInsets.symmetric(
horizontal: Constraints.paddingNormal),
child: Column(
.....
and after the list render I create the button like this
isNotScrollable
? Expanded(
child: Container(),
)
: Container(),
CVButton(
color: Palette.white,
Basically, my idea is: if the screen is not scrollable yet (the list content fits in the screen size) I will set a height to the container inside scrollview and add a Expanded() widget before the add button (so the button will stay in the bottom of the container), but if the screen is scrollable (the list content not fits inside the screen size) so I remove the container height and the Expanded widget, then the button will follow the list now as normally.
I don't know if this is the better way to deal with that, I want to know if there is some way to do this without this 'dinamic' way that I am doing, only with fixed widgets and not changing the widget according to the state of the scrollview.
An example when the list becomes scrollable and the button will keep at list bottom
Here the list is not scrollable yet but the button must be at the screen bottom and not list bottom
(I dont wanna use bottomNavBar)
Anyone has any idea how I can solve this?
I have a solution for this. check the code bellow. I added some buttons to add or remove cards. The main trick is to use constraints like minHeight.
import 'package:flutter/material.dart';
class BottomButton extends StatefulWidget {
#override
_BottomButtonState createState() => _BottomButtonState();
}
class _BottomButtonState extends State<BottomButton> {
List<Widget> cards = [];
#override
Widget build(BuildContext context) {
var appBar2 = AppBar(
actions: [
IconButton(
icon: Icon(Icons.add),
onPressed: () {
_addCard();
}),
IconButton(
icon: Icon(Icons.remove),
onPressed: () {
_removeCard();
}),
],
);
return Scaffold(
appBar: appBar2,
body: Container(
height: MediaQuery.of(context).size.height -
(MediaQuery.of(context).padding.top + appBar2.preferredSize.height),
alignment: Alignment.topCenter,
child: ListView(
primary: true,
children: [
Container(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height -
(MediaQuery.of(context).padding.top +
appBar2.preferredSize.height),
),
alignment: Alignment.topCenter,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height -
(MediaQuery.of(context).padding.top +
appBar2.preferredSize.height +
50),
),
alignment: Alignment.topCenter,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: cards,
),
),
ElevatedButton(
child: Text('this is a button'),
onPressed: () {},
),
],
),
)
],
),
),
);
}
void _addCard() {
Widget card = Card(
child: Container(
height: 100,
color: Colors.red,
padding: EdgeInsets.all(2),
),
);
setState(() {
cards.add(card);
});
}
void _removeCard() {
setState(() {
cards.removeLast();
});
}
}

RenderListWheelViewport object was given an infinite size during layout

I am using ListWheelScrollView Widget to give a wheeling effect to my list item but getting the error as mentioned. I just want to show Stacked Items with some image and texts in individual list item and give a 3D Wheeling effect to them.
Below is my code ->
class ExploreWidget extends StatefulWidget {
#override
State<StatefulWidget> createState() => _ExploreState();
}
class _ExploreState extends State<ExploreWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: null,
body: Column(
children: <Widget>[
_header(),
_exploreList()
],
)
);
}
Widget _header(){
return SizedBox(
height: 200,
width: 800,
);
}
Widget _exploreList(){
return ListWheelScrollView.useDelegate(
itemExtent: 75,
childDelegate: ListWheelChildBuilderDelegate(
builder:(context,index){
return Container(
height: 500,
width: 800,
child: Stack(
children: <Widget>[
Image(image: AssetImage(
_products[index].image
)),
Text(_products[index].name,style: Style.sectionTitleWhite,),
Text('70% off',style: Style.cardListTitleWhite,),
],
),
);
}
),
);
}
}
The error was occuring due to the way _exploreList() widget is implemented. This widget is wrapped inside Column which doesn't scroll in itself. Moreover, you are returning a ScrollView that has an infinite size. Hence it was throwing the said error. To resolve this issue, wrap _exploreList() widget inside Flexible which takes only minimum available space to render and scroll. Working sample code below:
body: Column(
children: <Widget>[
_header(),
Flexible(
child: _exploreList()
)
],
)
Now you should be able to use WheelScrollView properly.

Color of a widget inside a Stack is always slightly transparent

I display a custom-made bottom app bar in a Stack because of keyboard padding reasons. The custom widget is fully opaque as it should be until it's a child of a Stack in which case, the content behind it starts to be visible since the color's opacity somehow changes.
As you can see, it's only the "main" color that's transparent. Icons remain opaque.
This is the build method of my custom BottomBar widget which is then just regularly put into a Stack. I have tried using a Material and even a simple Container in place of the BottomAppBar widget but the results are the same.
#override
Widget build(BuildContext context) {
return BottomAppBar(
color: Colors.blue.withOpacity(1),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(MdiIcons.plusBoxOutline),
onPressed: () {},
),
Text('Edited 11:57'),
IconButton(
icon: Icon(MdiIcons.dotsVertical),
onPressed: () {},
),
],
),
);
}
Can you interact with the BottomAppBar ? It looks like an order problem. Try to put the BottomAppBar as last in the Stack children.
Note that BottomAppBar doesn't have a constant size, if you did not add it to Scaffold bottomNavigationBar named parameter has a size if this is not null. Below is peace of code in Scaffold dart file:
double bottomNavigationBarTop;
if (hasChild(_ScaffoldSlot.bottomNavigationBar)) {
final double bottomNavigationBarHeight = layoutChild(_ScaffoldSlot.bottomNavigationBar, fullWidthConstraints).height;
bottomWidgetsHeight += bottomNavigationBarHeight;
bottomNavigationBarTop = math.max(0.0, bottom - bottomWidgetsHeight);
positionChild(_ScaffoldSlot.bottomNavigationBar, Offset(0.0, bottomNavigationBarTop));
}
You can even develop your own Widget without BottomAppBar but if you want things like centerDocked and things like circular notched, you will have to do more stuff (anyway you have flexibility to custom design the way you want).
Here is a simple example to do that(one way to do that):
import 'package:flutter/material.dart';
class CustomBottomBar extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 50),
color: Colors.greenAccent, // if you want this color under bottom bar add the margin to list view
child: ListView.builder(
itemCount: 100,
itemBuilder: (_, int index) => Text("Text $index"),
),
),
Positioned(
bottom: 0,
child: Container(
color: Colors.amber.withOpacity(.5),
width: MediaQuery.of(context).size.width,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(4, (int index) => Text("Text $index")), // you can make these clickable by wrapping with InkWell or any gesture widget
),
),
),
],
),
);
}
}