Why does MainAxisAlignment of a Column have different outputs in flutter? - flutter

I used mainAxisAlignment: MainAxisAlignment.end, in my "Column" to place some content on the bottom of the screen. This works fine.
I needed to add a picture, this picture was also shown at the bottom of the screen, align and positioned didn't change it. So I put the Column as a child in another column, this allows me, to put the picture in a row, and place it in the right top corner. But now the content of the original column is centered in the screen. What should I do?
Should look like this:
Here my code:
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/Images/backgroundhomescreen.png'),
fit: BoxFit.cover,
),
),
child:Column(
children: [
Row( //Logo
children: [
Image(
image: AssetImage('assets/Images/logo.png'),
width: 120,
),
]
),
Column(
//crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[...

You can either set the crossAxisAlignment to CrossAxisAlignment.end to align all the children to the right or wrap the TopBox widget in Align.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container( //Outer Container
height: 900,
width: 400,
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
// Align(
// alignment: Alignment.centerRight,
// child: TopBox()
// ,),
TopBox(),
Spacer(),
BottomBox(),
],
),
);
}
}
class BottomBox extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
height: 200,
);
}
}
class TopBox extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(15),
color: Colors.blue,
height: 100,
width: 175,
);
}
}

You could simply achieve custom spacing in flutter using the spacer widget

Related

Can't align children of Rows by using the Align Widget and alignment property

I'm having some hard time using Alignments in Flutter. I'm trying to create a disposable card.
I can't have the Image centerd and the icon placed on the top right corner.
Widgets Explanation
The Card consists of Columns and each Column has a Row
The x Icon is the first child of the first Row
I wrapped the Icon with Align Widget but it won't move on the right:
Row(children: [
Align(
alignment: Alignment.topRight,
child: Icon(Icons.cancel),)
]
)
For the owl image i wrapped it inside a Container and used the alignment property to place in the the Center:
Row(children: [
Container(
width: 100,
height: 150,
alignment: Alignment.center,
child: Image(
alignment: Alignment.center,
image: NetworkImage('https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg'),
)
),
]),
Seems like no matter what I try on the layout it just won't move the objects inside the Card
Here is the Card Widget:
class CustomCard extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(children: [
Align(
alignment: Alignment.topRight,
child: Icon(Icons.cancel) ,
)
]
),
SizedBox(
height: 8,
),
Row(children: [
Container(
width: 100,
height: 150,
alignment: Alignment.center,
child: Image(
alignment: Alignment.center,
image: NetworkImage(
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg'),
))
]),
],
));
}
}
No matter what i try i can't have them placed correctly, have I completely missed the concepts of Align widget and alignment property?
All you needed to do was set the MainAxisAlignment to center for the Row. Please run the code below.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: CustomCard(),
),
);
}
}
class CustomCard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: Alignment.topRight,
child: Icon(Icons.cancel),
),
SizedBox(
height: 8,
),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
width: 100,
height: 150,
child: Image(
image: NetworkImage(
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg'),
))
]),
],
));
}
}

SVG file expoerted flat in flutter

I'm doing a simple landing page using flutter. When I try to use an SVG file, the file somehow is flat, isn't it supposed to be not flat??
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:simple_app/my_icon.dart';
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Column(
children: <Widget>[
Container(
height: size.height*0.6 ,
width: double.infinity,
decoration: new BoxDecoration(
color: Colors.blueAccent,
),
child: Column(
children: <Widget> [
Align(
child: SvgPicture.asset(
dika,
),
alignment: Alignment.topLeft,
),
],
),
),
],
);
}
}
I tried your code and it works fine, I assume your .svg file is broken, you could try to remove shadows and filter effects from your svg, they're not supported.
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class Test extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Column(
children: <Widget>[
Container(
height: size.height*0.6 ,
width: double.infinity,
decoration: new BoxDecoration(
color: Colors.blueAccent,
),
child: Column(
children: <Widget> [
Align(
child: SvgPicture.asset(
'assets/hexagon.svg',
),
alignment: Alignment.topLeft,
),
],
),
),
],
);
}
}
SVG in top left corner:

Flutter SingledChildScrollView > Stack > Positioned is glitches on Scroll

I am using a SingleChildScrollView with a Stack as its first element. The Stack contains two containers. The second one is positioned at bottom: 0.0 using a Positioned.
I highly simplified my view for this post to focus only on this issue. When I scroll slowly, you can see that the white container is "glitching" and you see a line that is the bottom of the first child of the stack.
Here is the view:
Not that's what happen when I scroll down, I have no clue why it's glitching like that:
View:
return Container(color: Colors.white, child: SingleChildScrollView(child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
HeaderComponent(),
Container(height: 600, width: MediaQuery.of(context).size.width)
]
)));
Header Component
class _HeaderComponentState extends State<HeaderComponent> {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(height: 245.0, width: MediaQuery.of(context).size.width, color: Colors.red),
Positioned(bottom: 0.0, child: Container(height: 40.0, width:
MediaQuery.of(context).size.width, color: Colors.white)),
],
);
}
}
If that, just add bottom padding 0.2 at first child.
class HeaderComponent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: 245.0,
padding: EdgeInsets.only(bottom: 0.2),
width: MediaQuery.of(context).size.width,
color: Colors.red),
Positioned(
bottom: 0.0,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width,
color: Colors.white)),
],
);
}
}
I don't know root cause. But Positoned's 'bottom: 0.0' occurs upper container's background color a little during scrolling.
So when I set 'bottom: -0.2', this problem is not occured.
But it does not looks cool...
class HeaderComponent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: 245.0,
width: MediaQuery.of(context).size.width,
color: Colors.red),
Positioned(
bottom: -0.2,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width,
color: Colors.white)),
],
);
}
}
I suggest another solution like below.
class HeaderComponent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
height: 245.0,
child: Column(
children: <Widget>[
Expanded(
child: Container(
width: MediaQuery.of(context).size.width, color: Colors.red),
),
Container(
height: 40.0,
width: MediaQuery.of(context).size.width,
color: Colors.white)
],
),
);
}
}

Flutter set background image for a page

I want to set the image as the background color for the page but the code below seems not to work well. I'm not sure if there is something missing in my code or mistake inside. And there is no error message shown.
class LoginPage extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.tealAccent,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/background.png"),
fit: BoxFit.cover,
),
),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 50),
_signInButton(),
],
),
),
),
);
}
you have to just use stack widget just like this
Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/login.png"), fit: BoxFit.fill)),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: <YOUR CHILD COMPONENTS WILL BE PLACED HERE>
),
],
),
Hope it will help!

Align ListView's children to top and bottom

TL;DR
Is it possible to align ListView's children like Column's spaceBetween alignment?
Like in this screenshot:
Problem that I tried to solve:
In the beginning I had a Column widget with 2 children. The Column's alignment was set to spaceBetween. It was what I wanted, one widget at the top, one at the bottom. But then when I clicked to input to add credentials, the keyboard caused an overflow issue described in this GitHub issue. So to fix it, I replaced the Column with ListView. But now my children widgets are stuck at the top of the screen.
My full LoginScreen code:
import 'package:flutter/material.dart';
import '../widgets/button.dart';
import '../widgets/input.dart';
import '../widgets/logo.dart';
class LoginScreen2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Background(),
Wrapper(),
],
),
);
}
}
class Background extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Color(0xfff6f6f6),
Colors.white,
],
),
),
);
}
}
class Wrapper extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Logo(LogoColor.dummy_black),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(20),
child: BottomPart(),
),
),
],
);
}
}
class BottomPart extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Input('User name'),
Input('Password'),
Button(
'Log in',
onPressed,
),
],
);
}
void onPressed() {}
}
You could use ListView's property reverse
reverse: true,
And then change the order of the ListView children.
Find a solution. You should wrap your Column in IntrinsicHeight and ConstrainedBox with minHeight.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: IntrinsicHeight(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height,
),
child: Column(
children: [
Container(
height: 100,
width: double.infinity,
color: Colors.yellow,
child: Text('1', style: TextStyle(color: Colors.black)),
),
Spacer(),
Container(
height: 100,
width: double.infinity,
color: Colors.red,
child: Text('2', style: TextStyle(color: Colors.black)),
),
],
),
),
),
);
}
}
Try using SizedBox(height:50.0) // or any other value in b/w Logo widget and Align(bottom part).
return ListView(
children: <Widget>[
Logo(LogoColor.dummy_black),
SizedBox(height: MediaQuery.of(context).size.height/ 3),// you will get value which is 1/3rd part of height of your device screen
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(20),
child: BottomPart(),
),
),
],
);
Finally I found out soln to this problem. Use Code :`
Align(
alignment: Alignment.bottomCenter,
child: ListView(
shrinkWrap: true,
children: <Widget>[
// Your Widget Here
],
),
),
you can insert this between logo and Align
Expanded(child: SizedBox(height: 8)),
You could take out the bottom part from ListView, and put it in the last of Stack's children. Your Wrapper could look like:
Widget build(BuildContext context){
var bottomHeight = 120.0;//replaced with your BottomPart's height
return Stack(
children: [
ListView(),//your ListView
Positioned(
top: MediaQuery.of(context).size.height - bottomHeight,
child: SizedBox(
height: bottomHeight,
child: BottomPart(),
)
)
],
);
}