Vertically center content inside SingleChildScrollView with min height of screen height - flutter

I am trying to create a web layout that that consists of a scrollable column that has a min height of the screen height but can expand past the screen height if the content is too large. I have been able to create the scrolling container but I cannot vertically center the main content while still making the entire sections scrollable. The only working version I can get wont vertically center the content, I have to added a SizedBox above it to create padding to make it look centered but then its not responsive on different heights.
The parent of the content looks like this:
Container(
width: MediaQuery.of(context).size.width / 2,
height: double.infinity,
padding: const EdgeInsets.fromLTRB(100, 30, 100, 0),
child: SingleChildScrollView(
child: Column(
children: [
LoginLayout(),
SizedBox(height: 30),
],
),
),
),
Then to simplify the content column, its basically this:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
child: Image.asset(
'assets/images/2.0x/logo-full.png',
width: 125,
fit: BoxFit.contain,
),
),
// This column needs to be vertically centered if fits in the screen height
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text('Welcome Back!', style: _textTheme.headline2),
SizedBox(height: 10),
Text('Sign in to continue', style: _textTheme.bodyText2),
SizedBox(height: 60),
EmailInput(label: 'EMAIL'),
SizedBox(height: 30),
PasswordInput(label: 'PASSWORD'),
SizedBox(height: 60),
Button(
label: 'Login',
icon: Icons.link,
theme: ButtonColor.PRIMARY,
onPressed: () {},
),
],
),
],
);
I was able to apply an Expanded widget around the centered column which did work but then I lost the ability to scroll if the content was larger that the screen height.
Here is an example for reference as well

Not sure how to do that in SingleChildScrollView though,
try using ListView with shrinkWrap: true
Container(
width: MediaQuery.of(context).size.width / 2,
height: double.infinity,
padding: const EdgeInsets.fromLTRB(100, 30, 100, 0),
child: Center(
child: ListView(
shrinkWrap: true,
children: [
LoginLayout(),
],
)
),
)

Related

Doesn't fit all content on the page Flutter

Faced a problem. My content does not fit on the page, so I added SingleChildScrollView in the TabBarLibrary. And wrapped in Expanded. As a result, I got scrolling, but also the content size greatly decreased due to Expanded, I attached a screenshot below where you can see that an empty space has appeared. How can I make the content appear on the entire page and be able to scroll?
body
Column(
children: [
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
children: [
TabBarWidget(tabController: _tabController),
],
),
),
const SizedBox(height: 20),
_divider,
TabBarLibrary(
tabController: _tabController,
size: size,
),
],
);
TabBarLibrary
return Expanded(
child: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(maxHeight: widget.size.height * .69),
child: TabBarView(
controller: widget._tabController,
children: [
_tab1(),
Text('Tab2'),
Text('Tab3'),
],
),
),
),
);
}
tab1
return Column(
children: [
_divider,
const Padding(
padding: EdgeInsets.only(left: 24, top: 20),
child: Align(
alignment: Alignment.centerLeft,
//TODO dropdown
child: Text(
'DrowDown',
style: TextStyle(color: Colors.white),
),
),
)
...
without Expanded
Try remove ConstrainedBox, it limit your TabBarLibrary height.
Explain: You have already Expanded to determined height and a SingleChildScrollView inside wich want to fill there height, ConstrainedBox inside that limit the height, so content will not fill full the scrollview.
try wrap Expanded with SingleChildScrollView
return SingleChildScrollView(
child: Expanded(
child: ConstrainedBox(

Flutter Alignment Containers

So I'm working on my first Project. Basically I want to alignment 4 containers equally. they should have same size H/W so i could scroll on them whenever extra data has been put into them later.....
Here's my Code
Widget build(BuildContext context) {
return Center(
child: Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Row(
children: [
VerticalText1(),
DoBuilder(),
],
),
Column(
children: const [
SizedBox(
width: 10,
)
],
),
Column(
children: [
DecideBuilder(),
],
),
],
),
Row(
children: const [
SizedBox(
height: 10,
)
],
),
Row(
children: [
Row(
children: [
VerticalText2(),
DelegateBuilder(),
],
),
Column(
children: const [
SizedBox(
width: 10,
)
],
),
Align(
alignment: Alignment.bottomLeft,
child: DeleteBuilder(),
),
So I'm working on my first Project. Basically I want to alignment 4 containers equally. they should have same size H/W so i could scroll on them whenever extra data has been put into them later.....So I'm working on my first Project. Basically I want to alignment 4 containers equally. they should have same size H/W so i could scroll on them whenever extra data has been put into them later.....
for me I'm also a beginner in flutter but I know something that if you want actual size for container and you want it to be some kind of responsive you have 2 ways to do that:
first you can use:
(Mediaquery).of(context).size.width or
(media.query).of(context).size.height
that will give you the size of your screen and you can use as much as you need from it for each container for example:
Container(
child:,
width: (MediaQuery.of(context).size.width / 2))
that will give you half of your screen width what ever the device run the app the size will be the same for the screen size
and other way you can use expanded widget:
put every container in expanded widget and give the flex parameter value of one
here is an example:
Row(children:[
Expanded(flex:1,child:Container()),
Expanded(flex:1,child:Container()),]),
expanded will sum the flexes and will divide the space of the screen on element all equal repeat the above code in single Column has 2 Rows and I hope your code will work as you want
Instead of row and column, you should try with the GridView otherwise you can try with media query height and width.
GridView.builder(
itemCount: 4,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return new Card(
child: Container(
color: Colors.green,
child: Center(child: Text("$index"),),
),
);
},
)
And Using Column and row
idget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width-20;
return Scaffold(
appBar: AppBar(
title: Text("widget.title"),
),
body: Stack(
children: [
Column(
children: [
Expanded(
child: Row(
children: [
Container(
height: height / 2,
width: width/2,
color: Colors.green,
),
SizedBox(width: 10,),
Container(
height: height / 2,
width: width / 2,
color: Colors.green,
)
],
),
),
SizedBox(height: 10,),
Expanded(
child: Row(
children: [
Container(
height: height / 2,
width: width / 2,
color: Colors.green,
),
SizedBox(width: 10,),
Container(
height: height / 2,
width: width / 2,
color: Colors.green,
)
],
),
),
],
),
Center(
child: Padding(
padding: const EdgeInsets.only(right:10.0),
child: CircleAvatar(child: Icon(Icons.home),),
),
)
],
),
);
}
Output:

move singlechildscroll view back to top position after refresh in flutter

whenever I tap on any of the options of the given 4 buttons, my new data loads in the text and in the 4 option fields.
but the scroll view doesn't come back to its normal position, instead, it remains down, at what position I had left it, previously.
so how to get singlechildscrollview back to its original form after every refresh?
Expanded(
child: Container(
width: MediaQuery.of(context).size.width,
margin:EdgeInsets.only(top: 50.0,bottom: 50) ,
decoration: BoxDecoration(
color: Color(0xFFf2f2f2),
borderRadius: BorderRadius.only(topRight: Radius.circular(40),topLeft:Radius.circular(40) ),
),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
height: 800,
child: (
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 50,left: 20,right: 20),
child: Text(question.replaceAll("\\n", "\n"),style: TextStyle(fontWeight: FontWeight.bold,fontSize: 18),),
),
SizedBox(height: 20),
optionButton(text: option1),
SizedBox(height: 30),
optionButton(text: option2),
SizedBox(height: 30),
optionButton(text: option1),
SizedBox(height: 30),
optionButton(text: option2),
SizedBox(height: 30),
Spacer(),
Column(
children: [
Text("TOTAL"),
Container(
width: MediaQuery. of(context). size. width,
color: Colors.blue,
child:
Center(child: Text(score.toString(),)),),
SizedBox(height: 20)
],),
],
)
),
),
),
),
),
Since I'm not sure what optionButton looks like, you'll probably need this first above your build method:
ScrollController scrollController = new ScrollController();
Then if your optionButton is within the same class, call this within your button function onTap(){} or onPressed(){} :
scrollController.jumpTo(0.0);
Make sure to add the controller to SingleChildScrollView
If optionButton is from a different class, then I'll have to change my answer.
Let me know if this helps!

overflowing flutter columns and rows

I have this list view in flutter which I am trying to make into a chat list. Similar to what you see in WhatsApp and telegram. However I am struggling to get the idea of how rows and columns work because I keep getting overflows.
Here is the code:
ListView(
physics: BouncingScrollPhysics(),
children: [
Dismissible(
key: Key(""),
background: Container(color: Colors.grey[200]),
direction: DismissDirection.endToStart,
child: InkWell(
onTap: () {},
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flex(
direction: Axis.vertical,
children: [
Text("Hello"),
],
),
Flex(
direction: Axis.vertical,
children: [
Text(
"al;skdl;aksd a;skd ;aks;dk a;skd ;laks;d a;lsk d;lkas; dka;lsk d;laks; ldka;slk d;a",
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
],
),
],
),
),
),
],
Now we often experience the text overflow problem so if we think it that we we have provided column a particular width and restricted it but if we wrap the things up with flexible widget it now tells column/Row that you can change your size and be flexible
order would be
flexible > Container > Column/Row
The reason we are applying this to container is Column/Row will ask immediate parent for width and height
now this problem can also be solved by text overflow property that is we can clip text but what if we dont want too
So all you have to do is Wrap the column/Row in Container and then into Flexible as now it will tell container that yes you can adjust your height
Your concept can be cleared by how actually widgets parent child relationship works i.e in brief
basically If am a child I will ask my parent okay what is my size so since my parent if it has a size it will bound me but if it doesnt has a size it will ask its parent okay tell me what space should I take and it goes on. Expanded and Flexible says that okay you can adjust yourself instead of being Fixed.
Flexible(
child: Container(
margin: EdgeInsets.only(left: 10.0,right: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${dataBookTitleSearch1[index]} ', style: kGoodSearchResultTextStyle, textAlign: TextAlign.left,),
SizedBox(
height: 10.0,
),
Text('${dataBookAuthorSearch1[index]}', style: kGoodSearchResultTextStyle,textAlign: TextAlign.left),
SizedBox(
height: 10.0,
),
Text('${dataBookExtensionSearch1[index]} ', style: kGoodSearchResultTextStyle,textAlign: TextAlign.left),
SizedBox(
height: 20.0,
),
Container(
width: 80.0,
height: 40.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Colors.white
),
child: Padding(
padding: const EdgeInsets.only(left:20.0,top: 12.0),
child: Text('Read'),
),
),
],
),
),
)

Word-wrapping do not working with long text

Here is my widget:
return Card(
child: Container(
height: 150,
child: Row(
children: <Widget>[
Placeholder(
fallbackHeight: 100,
fallbackWidth: 100,
),
Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Flexible(
child: Text(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
overflow: TextOverflow.ellipsis,
maxLines: 4,
)),
// Expanded(flex: 8, child: Text("bbb")),
Flexible(child: Text("bbb")),
// Flexible(child: Text("aaa")),
],
),
)
],
),
));
I expected that text will be placed on new line, but I am getting overflow:
Wrap your inner Container with an Expanded to provide it with the available parent constraints, otherwise the Container has infinite height and will result in an overflow (because you are on landscape).
Expanded(
child: Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
...
You could wrap the second element of the Row with Flexible, like this:
Row(
children: <Widget>[
Placeholder(..),
Flexible(
child: Container(
color: Colors.red,
child: Column(...
Inside the Row you need Placeholder to keep its width and Container width to be flexible.
Edit: And you should remove the width of the Container, since it would be flexible and it should take as much as possible to fit the screen.