SingleChildScrollView makes the UI white - flutter

I am trying to make my UI scrollable but when i add the SingleChildScrollView i get this white screen not showing anything at all.I should erase the Column from the begining?Use a container?I already search on internet but i don't know what to add.
Here is my code, please tell me what i can erase or add to make it work ..
class _UserProfilesState extends State<UserProfiles> {
#override
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Expanded(
child: Stack(
children: <Widget>[
Padding(
padding:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 40.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
iconSize: 30.0,
color: Colors.black,
onPressed: () => Navigator.pop(context),
),
])),
Positioned(
left: 24,
top: MediaQuery.of(context).size.height / 6.5 - 28,
child: Container(
height: 84,
width: 84,
//profilepic
child: CircleAvatar(
radius: 10,
backgroundImage: NetworkImage(widget.avatarUrl != null
? widget.avatarUrl
: "https://icon-library.com/images/add-image-icon/add-image-icon-14.jpg"),
),
),
),
Positioned(
right: 24,
top: MediaQuery.of(context).size.height / 6.5 + 16,
child: Row(
children: <Widget>[
Container(
height: 32,
width: 100,
child: RaisedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ChatScreen(
serviceProviderId:
widget.serviceProviderId,
userName: widget.userName,
avatarUrl: widget.avatarUrl,
)));
},
color: Colors.black,
textColor: Colors.white,
child: Text(
"Message",
style: TextStyle(fontWeight: FontWeight.bold),
)),
),
SizedBox(
width: 16,
),
Container(
height: 32,
width: 32,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://lh3.googleusercontent.com/Kf8WTct65hFJxBUDm5E-EpYsiDoLQiGGbnuyP6HBNax43YShXti9THPon1YKB6zPYpA"),
fit: BoxFit.cover),
shape: BoxShape.circle,
color: Colors.blue),
),
],
),
),
Positioned(
left: 24,
top: MediaQuery.of(context).size.height / 4.3,
bottom: 0,
right: 0,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.userName,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 22,
)),
SizedBox(
height: 4,
),
Padding(
padding: const EdgeInsets.all(1.0),
child: Text(
widget.address == "default"
? "No Address yet"
: "${widget.address}",
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
)),
Padding(
padding: const EdgeInsets.all(1.0),
child: Text(
"${widget.categoryName}",
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
)),
],
),
))
],
))
],
),
),
);
}
}

Using Spacer() might also cause this issue

The reason why your UI became white is that SingleChildScrollView allows it child to take as much space as possible. In your Column, one of your children is Expanded, Expanded tries to take as much space as possible. You are making your UI take an infinite amount of space because of that. That's the reason why you are seeing a white screen. The solution here would be to remove Expanded.

according to me and the knowledge I have this happened because the singlechildscrollview here tries to take as much height as it can take so It is creating an issue to solve this wrap the singlechildscrollview in a container and give height&width to the container it solved in my case
Thanks...

I faced similar issues, but after much research I got it working, by ensuring that the body of the scaffold be a Container that defines it's height and width, or Column. After which you can wrapped your any of these with a SingleChildScrollView.
However, in an attempt to insert an Expanded widget as child element, the expanded widget will look for bounded heights of it's parents/root element. And if it doesn't found any, it will thrown an error. A good example is if the root element is a column or a container with an unbounded height. Which is your case, looking at your code

Related

Unable to wrap Text inside Container in Flutter

I have the following tree: Scaffold > Column > Row > Container > Text.
I want the Text to wrap, and The Great Google in most cases told me that Expanded is what i need, but none of the below cases worked for me:
Row wrapped inside Expanded
Container wrapped inside Expanded
Text wrapped inside Expanded
All of the above have the same result.
Here's my code for the page's body:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF282B32),
body: Column(
children: <Widget>[
createRow(
context,
"https://i.stack.imgur.com/6Utrc.jpg?s=256&g=1",
"GuildProtect is a powerful, baterries-included moderation bot for your *safe* server!"
),
createDivider(),
createRow(
context,
"https://cdn.discordapp.com/avatars/967406876029501462/bd3c60dcf55c83fba41b15fba89f798a.webp?size=256",
"This is a very beatiful (because it's pink) avatar of this shitty website creator, enjoy!"
)
]
)
);
}
Row createRow(BuildContext context, String imageUrl, String text) {
const containerHeight = 256.0;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25, bottom: 25),
child: Image.network(imageUrl),
),
Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 1.3).fontSize,
),
),
),
]
);
}
Divider createDivider() {
return const Divider(
color: Color(0xFF131518),
indent: 30,
endIndent: 30,
thickness: 1,
height: 20,
);
}
}
I also saw some answers on SO recommending to cut the text or show ellipsis, but i dont need this behaviour, i need the text to actually wrap. This video's second solution shows exactly what i want to achieve (and no, the solution from there didn't help).
Any help is appreciated!
In createRow(), wrap the second Container() with Flexible().
Flexible(
child: Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: DefaultTextStyle.of(context)
.style
.apply(fontSizeFactor: 1.3)
.fontSize,
),
),
),
)
Lemme know if it worked for your use case.
Why are you seeing this?.
Well, this is because the width of the widgets which you are trying to put, is greater then the screen size.
Possible solutions:
Try to add width property to the second Container in the Row
try to use .fit property, which will fit the image in it's father widget size.
I don't think that wrapping the container in Expanded wouldn't fix the situation as I see the text is too long (the screen has overflowed by 260 pixels).
Try to use TextOverflow as mentioned in link.
Please, let me know if any of my solutions works.
Anywhere you want to use a text and its length is not specified, you may encounter a folding error.
My suggestion is to use Expanded.
This is the output of your code snippet in my simulator
your code Output in mobile
It is enough to wrap the second Container with an Expanded widget (createRow) :
Row createRow(BuildContext context, String imageUrl, String text) {
const containerHeight = 256.0;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25, bottom: 25),
child: Image.network(imageUrl),
),
--> Expanded(
child: Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 1.3).fontSize,
),
),
),
),
]
);
}
and output:
--> after Wrap Container with Expanded Widget
It is noteworthy that this part of your work is not responsive.
Probably, the texts are too big in my emulator because of the difference made by the DefaultTextStyle.of(context) class.
Anyway, I hope it solved your problem.
full code:
I used MediaQuery for setting fontSize Because no details are provided from the content of the defaultTextStyle class.
import 'package:flutter/material.dart';
class TstPage extends StatelessWidget {
const TstPage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF282B32),
body: Column(
children: <Widget>[
createRow(
context,
"https://i.stack.imgur.com/6Utrc.jpg?s=256&g=1",
"GuildProtect is a powerful, baterries-included moderation bot for
your *safe* server!"
),
createDivider(),
createRow(
context,
"https://cdn.discordapp.com/avatars/967406876029501462/bd3c60dcf55c83fba41b15fba89f798a.webp?size=256",
"This is a very beatiful (because it's pink) avatar of this shitty
website creator, enjoy!"
)
]
)
);
}
Row createRow(BuildContext context, String imageUrl, String text) {
const containerHeight = 256.0;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: containerHeight,
padding: const EdgeInsets.only(left: 50, top: 25, bottom: 25),
child: Image.network(imageUrl),
),
Expanded(
child: Container(
alignment: Alignment.centerRight,
height: containerHeight,
padding: const EdgeInsets.only(right: 50, top: 25),
child: Text(
text,
style: TextStyle(
color: const Color(0xFFFFFCF9),
fontWeight: FontWeight.bold,
fontSize: MediaQuery.of(context).size.width*0.04,
),
),
),
),
]
);
}
Divider createDivider() {
return const Divider(
color: Color(0xFF131518),
indent: 30,
endIndent: 30,
thickness: 1,
height: 20,
);
}
}

responsive design resize problem - flutter

Widget myPost(double screenH, BuildContext context, double screenW) {
String sampleSrc =
"https://images.unsplash.com/photo-1475924156734-496f6cac6ec1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80";
return Container(
margin: const EdgeInsets.symmetric(vertical: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
constraints: BoxConstraints(minWidth: screenW * 0.1),
height: screenH * 0.1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
const CircleAvatar(
radius: 30,
),
SizedBox(
width: screenW * 0.01,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"QWE QWE",
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"27 min",
),
const Icon(
Icons.enhanced_encryption_sharp,
size: 12,
),
],
),
],
),
],
),
const Icon(Icons.more_vert_sharp),
]),
),
),
ReadMoreText(
"text" * 800,
trimCollapsedText: "Read More...",
trimExpandedText: "Read less",
trimLines: 3,
style: const TextStyle(fontSize: 20),
trimMode: TrimMode.Line,
moreStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
lessStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
InkWell(
onTap: () {},
child: Container(
constraints: BoxConstraints.loose(Size.fromHeight(screenH * 0.5)),
child: Image.network(
sampleSrc,
fit: BoxFit.fitWidth,
width: double.infinity,
),
),
),
],
),
);
}
My design
I'm using the responsive_framework package, but when I reduce the height, all the widgets resizing, and I get overflows. The design I'm trying to make is like the following GIF the design that I want
Just like in responsive sites, I want the widgets to be fixed and only scrollable, no matter how much the height decreases.
Any trick or document to do this ?
The overall height on shrink is greater than height: screenH * 0.1, you can include extra pixels like height: 10+ (screenH * 0.1) But you can just include fixed height here. Like on item, you can choose minimum fixed height like 64, and you don't to have to worry about making larger. You can also check your attached GIF row height doesn't change.
Second option is wrapping Text with FittedBox widget, or using auto_size_text.

How can I change the width of a container/card depending on screen size?

I tried adding a width to the container but it didn't do anything. By default it fills the page? Not sure what's happening. Do I have to use MediaQuery somewhere? I want the post to be the same size on both the phone and the tablet. I'm not great with explaining so I added a photo to help.
Here's my code:
body: ListView(
children: [
Container(
height: 132,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Column(
children: <Widget>[
ListTile(
leading: CircleAvatar(
backgroundColor: Color(0xFF192A4F),
),
title: SizedBox(
height: 39,
child: TextButton(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
'Username',
style: TextStyle(
color: Color(0xFF192A4F),
fontSize: 16,
fontWeight: FontWeight.bold),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size(50, 30),
alignment: Alignment.centerLeft),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SeventhRoute(),
),
);
},
),
),
),
Divider(
height: 10,
color: Colors.black26,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.comment_outlined,
color: Colors.black),
SizedBox(width: 8.0),
Text(
'Comment',
style: TextStyle(color: Colors.black),
),
],
),
Row(
children: <Widget>[
Icon(Icons.bookmark_outline, color: Colors.black,),
SizedBox(width: 8.0),
Text('Bookmark', style: TextStyle(color: Colors.black),),
],
),
],
),
SizedBox(
height: 12.0,
)
],
),
),
),
],
),
double width = MediaQuery.of(context).size.width;
you can get screen width from here. Then add a logic
As example if screen width of right phone is 500 and left is 1000,
then you can set
if the screen width is <= 500 ,
set the container width as screen width
otherwise
set the container width as 500.
---Additionally---
You can get screen orientation like this
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait
The reason specifying the width is ignored is because you didn't specify what should happen with the smaller card. The framework doesn't know if it should be aligned left, center, right, etc. To fix this, you can wrap your Card, Container, or even the whole ListView in a Center (or Align) widget.
Based on your images i can see that only the width is changing, height is constant, so i'd suggest in your container give width: MediaQuery.of(context).size.width;
And of course some padding to that container.
It looks like you want that widget to take as much width as it can, but no more than 500px wide. Trivial:
ConstrainedBox(
child: YourChild(...),
constraints: BoxConstraints(maxWidth: 500),
),

How do I stretch a container in flutter so that it occupies the remaining screen?

I'm trying to maximize the screen as there is an unused white gap at the bottom (below the green bar which is the countdown/timer for the qn) :
Code:
final quizBottomContentText = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(left:30.0, right:30.0, top: 30.0, bottom: 30),
child: Text(
questions[questionNum].title,
style: TextStyle(fontSize: 18.0),
)
);
final quizOptions = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(left: 40.0, right:40.0, bottom: 40.0),
child: Center(
child: Column(
children: questions[questionNum].options.map<Widget>(
(option) => SimpleRoundButton(
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
buttonText: Text(option,
style: TextStyle(
color: Colors.white
),
),
textColor: Colors.white,
onPressed: (){},
),
).toList(),
)
)
);
final countdown = CountdownWidget(
width: MediaQuery.of(context).size.width,
duration: 20,
triviaState: triviaState,
);
final quizBottomContent = Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: <Widget>[quizBottomContentText, quizOptions, countdown], // need countdown
),
);
I've been trying the following but I cant seem to get what I want:
// Column for quizBottomContent
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Wrap your bottom widget in Column inside Expanded (I think, this is what you want)

Auto expanding Container in flutter -- for all devices

I need a Container with some text in to auto expand. I have an API call, which can be anything from 5 words to 500 words. I don't want to just have 1 fixed size that's huge, but contains 10 words.
I have tried Expanded() and SizedBox.Expand(), but I might be using them wrong
Card(
elevation: defaultTargetPlatform ==
TargetPlatform.android ? 5.0 : 0.0,
child: Column(
children: <Widget>[
Container(
margin: const EdgeInsets.all(0.0),
padding: const EdgeInsets.all(2.0),
decoration: BoxDecoration(color: Colors.black),
width: _screenSize.width,
height: 250,
child: Column(
children: <Widget>[
Container(
color: Colors.black,
width: _screenSize.width,
height: 35,
child: Padding(
padding: const EdgeInsets.only(
left: 15, top: 11),
child: Text("Title".toUpperCase(),
style: TextStyle(
color: Colors.white
),
),
),
),
Container(
color: Colors.white,
width: _screenSize.width,
height: 210,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 5),
child: Text("Title of expanding text", style: TextStyle(
fontSize: 25,
),
),
),
Text("Expanding text", style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.w800
),),
],
),
),
],
),
),
],
),
),
I just need the Container to expand, but stay small/get bigger
Have you tried not specifying height at all? The Container should wrap according to the child in this case.
Otherwise, the widget has a child but no height, no width, no
constraints, and no alignment, and the Container passes the
constraints from the parent to the child and sizes itself to match the
child.
Above is an extract from the official flutter documentation for Container.
Here is the official flutter documentation link.
You can use FittedBox, this will resize your text according to available area.
You can use it like this :
FittedBox(child: Text('...............Your text...............'));
I would suggest you to use Constraints...this will set Container height according to the Text child's requirement. Please see the example...
Container(
constraints: BoxConstraints(
maxHeight: double.infinity,
),
child: Column(
children: [
Text(
'Hello flutter...i like flutter...i like google...',
softWrap: true,
style: TextStyle(
color: Colors.white, fontSize: 20 , ),
),],),)
we just neeed to add mainAxisSize: MainAxisSize.min, properties inside child Column or Row where the child is set to Container
for example
AnythingYourWidget(
child: Container(
child: Column( // For Example Column
mainAxisSize: MainAxisSize.min, // these properties following the children content height available.
children: [
// YourWidget
]
)
)
),
I too had a container with a text widget inside that would not scale as the text increased in character count. Make the widget tree Container -> IntrinsicWidth -> Text/TextField and it seems to play nicely for me.
IntrinsicWidth will scale the size of the container to its child.