Flutter (Dart): Exceptions caused by rendering / A RenderFlex overflowed - mobile

I have a problem with Flutter (Dart) RenderFlex overflowed pixels. An exception of rendering library.
How can I manage or apply scrolling ability to my app page view and avoid Flutter's rendering exceptions with messages like:
A RenderFlex overflowed by 28 pixels on the bottom.
if you by any chance need the full log to help me is here:
on the hot-reload it comes up with the yellow/black stripes at the bottom as per the message.
Is this something I can manage with a scrollable widget? Or I can declare otherwise my widgets in order to control it?
full code if needed (i changed the Text data but assume the texts appearing are longer than the screen size, and thus the error comes up):
#override
Widget build(BuildContext context) {
return new DefaultTabController(
length: 3,
child: new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: [
new Tab(text: "xxx",),
new Tab(text: "xxx",),
new Tab(text: "xxx",),
],
),
title: new Text(data["xxx"]),
),
body: new TabBarView(
children: [
new Column(
children: <Widget>[
new Text(data["xxx"],
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.blue,
fontSize: 16.0
),),
new Text(data["xxx"],
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.blue,
fontSize: 10.0
),),
new Text(data["xxx"],
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.blue,
fontSize: 16.0
),),
new Text(data["xxx"],
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.blue,
fontSize: 8.0
),
),
new Text(data["xxx"],
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.blue,
fontSize: 8.0
),),
new Row(
children: <Widget>[
new Expanded(
child: new Text("xxx"),
),
new Expanded(
child: new Icon(Icons.file_download, color: Colors.green, size: 30.0,),
),
],
),
new Divider(),
new Text("xxx",
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.red,
fontSize: 16.0
),
),
],
),
new ListView.builder(
itemBuilder: (BuildContext context, int index) => new EntryItem(_lstTiles[index]),
itemCount: _lstTiles.length,
),
new Column(
children: <Widget>[
new Text(data["xxx"],
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.green[900],
fontSize: 16.0
),
),
new Text(data["xxx"],
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.green[900],
fontSize: 16.0
),),
new Text(data["xxx"]),
new ListTile(title: new Text("xxx")),
new Text(data["xxx"]),
new ListTile(title: new Text("xxx")),
new Divider(),
new Text("xxx",
style: new TextStyle(
fontStyle: FontStyle.italic,
color: Colors.red,
fontSize: 16.0
),
),
],
),
],
),
),
);
}

This is a pretty common issue to run into, especially when you start testing your app on multiple devices and orientations. Flutter's Widget gallery has a section covering the various scrolling widgets:
https://flutter.io/widgets/scrolling/
I'd recommend either wrapping your entire content in a SingleChildScrollView, or using a scrolling ListView.
EDIT: This question and answer have gotten some notice, so I'd like to provide a little more help for those who land here.
The Flutter SDK team puts a lot of effort into good documentation within the SDK code itself. One of the best resources for understanding the algorithm that Flex widgets (Row and Column are both subclasses of Flex) use to lay out their children is the DartDoc that accompanies the class itself:
https://github.com/flutter/flutter/blob/e3005e6962cfefbc12e7aac56576597177cc966f/packages/flutter/lib/src/widgets/basic.dart#L3724
The Flutter website also contains a tutorial on building layouts and an interactive codelab about how to use Row and Column widgets.

Let's say you have a List of 100 Text widgets like this:
final children = List<Widget>.generate(100, (i) => Text('Item $i')).toList();
Depending on the device screen, these widgets can overflow, there are few solutions to handle it.
Use Column wrapped in SingleChildScrollView
SingleChildScrollView(
child: Column(children: children),
)
Use ListView
ListView(
children: children
)
Use combination of both Column and ListView(you should use Expanded/Flexible, or give a fixed height to the ListView when doing so).
Column(
children: [
...children.take(2).toList(), // show first 2 children in Column
Expanded(
child: ListView(
children: children.getRange(3, children.length).toList(),
), // And rest of them in ListView
),
],
)

I was also facing this issue, try this ....
resizeToAvoidBottomPadding: false,
Before the body part
EDIT - 1
resizeToAvoidBottomPadding is deprecated
resizeToAvoidBottomInset: false

You can use the widget Expanded for each container inside the column. And then use flex to make the correct adjustments.

I you are using column, wrap you inner-widget with expanded like this
Expanded(
child: Center(
child: Image(
image: AssetImage('assets/icons/${menuItem.iconData}'),
),
),
),

You can wrap the text in PreferredSize widget:
bottom: PreferredSize(
preferredSize: Size.fromHeight(120.0),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
right: 5.0, left: 5.0, bottom: 2.0, top: 2.0),
child: Text(
hospitalName,
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 14.0),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Container(
height: 1.0,
width: MediaQuery.of(context).size.width,
color: Colors.white,
),
),
Padding(
padding: EdgeInsets.only(
top: 2.0, right: 5.0, left: 5.0, bottom: 2.0),
child: Text(
doctorName,
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 14.0),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Container(
height: 1.0,
width: MediaQuery.of(context).size.width,
color: Colors.white,
),
),
TabBar(
isScrollable: true,
tabs: [
Tab(
text: "Tab1",
),
Tab(text: "Tab2"),
Tab(text: "Tab3"),
],
),
],
)),

For me, I added a text to one of row children, i was fetching data from firebase and it was null. So make sure there is some data coming.

Related

How I use data from database So that I don't Have to add hundred thousand of images in assets in flutter?

Beginner here,
I have never used database before.
I am creating an flutter app which contain product images and its affiliate link...but my app size is getting bigger because in assests i have uploaded hundreds of images which is taking lots of space..
Is there any way i can fetch data from backend or something like that ...
enter image description here
i want this type of UI..
enter image description here
And this my code for it...
enter code here: SliverToBoxAdapter(
child: SizedBox(
child: Column(
children: [
// ignore: prefer_const_constructors
Padding(
padding: const EdgeInsets.only(right: 210.0),
// ignore: prefer_const_constructors
child: Text(
"Great Personality",
// ignore: prefer_const_constructors
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
),
Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
height: 200,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
child: Container(
width: 120,
color: Colors.amber,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 120,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 120,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 120,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 120,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 120,
color: Colors.white,
),
),
],
),
),
)
],
)
],
),
),
),
Use Cached Network Image and fetch from firebase or any other server. (Works offline as long as the image has been loaded before.)
if your app will work on ofline mode it will crash
Yes, Use Firebase Storage to store your images and fetch images from there.

Randomly display values from an array excluding value in index 0 in flutter

I am a beginner in flutter. I was building an app as a part of learning and came across this confusion. I have an array with some names and I wanna display those names randomly on button press. I left the index 0 value as null so that every time the app loads no names are displayed. The problem is when i press the button this null value is also displaying. Please help me.
class _FoodieState extends State<Foodie> {
List<String> foodieName = ['','foodie1', 'foodie2', 'foodie3', 'foodie4', 'foodie5','foodie6','foodie7'];
int foodieNumber=0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
radius: 120.0,
backgroundImage: AssetImage('images/burger.jpg'),
),
ElevatedButton(
child: Text('Who will buy today\'s\ lunch ?'),
style: ElevatedButton.styleFrom(
primary: Colors.yellow[800],
onPrimary: Colors.white,
shape: const BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
textStyle: TextStyle(
fontFamily: 'Rancho',
fontSize: 35,
color: Colors.grey,
),
),
onPressed: () {
setState(() {
foodieNumber=Random().nextInt(foodieName.length);
});
},
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Text(
foodieName[foodieNumber],
style: TextStyle(
fontFamily: 'Pacifico',
fontSize: 30,
color: Colors.red,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
);
}
}
This doesnt display first index:
foodieNumber=Random().nextInt(foodieName.length - 1) + 1;

Reading arrays from Firestore and inserting to a list in Flutter

Im having problem reading arrays from Firestore, strings can be readable within future builder as below,
How ever when its time to read array field in very same document and insert in a list is just not working , actually Im not able to read the array with get method. tried [] method but always receving getting null error, List experiences = snapshot.data.get('experiences') is not working for arrays,
Is there a different method for reading arrays from firebase ? I also need to read that array put in a list and use it to list the selected data from each index to a listview as usually we do locally with lists.
Here is the error message:
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building FutureBuilder(dirty, state: _FutureBuilderState#395a0):
The method 'get' was called on null.
Receiver: null
Tried calling: get("experiences")
The relevant error-causing widget was:
FutureBuilder file:///xxxxxxxx/lib/regformSummary.dart:185:45
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 _RegFormSummaryState.build. (package:xxxxxx/regformSummary.dart:186:94)
#2 _FutureBuilderState.build (package:flutter/src/widgets/async.dart:773:55)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
...
here is working code for reading strings
//under main widget builder
DocumentReference resumedata =_firestore.collection('users').doc(widget.userID).collection('resume').doc('info');
DocumentReference userdata = _firestore.collection('users').doc(widget.userID).collection('resume').doc('personalinfo');
//
.....,
FutureBuilder(future:userdata.get(),builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if(snapshot.connectionState == ConnectionState.done){
String profilepic = snapshot.data.get('profilepic');
String name = snapshot.data.get('name');
String sname = snapshot.data.get('sname');
return Column(
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: CircleAvatar(
minRadius: 40,
maxRadius: 80,
backgroundImage: NetworkImage('$profilepic'),
),
),//avatar
Padding(
padding: EdgeInsets.symmetric(horizontal: 10,vertical:3),
child: Text(
name,
style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.black54,fontSize: 24,fontWeight: FontWeight.bold)),
),
),//name
Padding(
padding: EdgeInsets.symmetric(horizontal: 10,vertical:3),
child: Text(
sname,
style: GoogleFonts.openSans(textStyle: TextStyle(color: Colors.black54,fontSize: 24,fontWeight: FontWeight.bold)),
),
),//sname
],
);
}
return SizedBox();
}),
Here is the failing code
DefaultTabController(
length:8,
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
children: [
TabBar(
isScrollable: true,
indicatorWeight: 4.0,
indicatorColor:Colors.black38,
unselectedLabelColor: Colors.black38,
tabs: <Widget>[
Tab(
child:Text('Tecrübeler',style: TextStyle( color:
colorVal
)),
),
Tab(
child: Text('Eğitim',style: TextStyle( color: colorVal
)),
),
Tab(
child: Text('Yabancı Dil',style: TextStyle( color: colorVal)),
),
Tab(
child: Text('Sertifikalar',style: TextStyle( color: colorVal)),
),
Tab(
child: Text('Referanslar',style: TextStyle( color:colorVal)),
),
Tab(
child: Text('İlgilendiği Pozisyonlar',style: TextStyle( color: colorVal)),
),
Tab(
child: Text('CV dosyası ve Önyazı Dosyası',style: TextStyle( color: colorVal)),
),
Tab(
child: Text('İletişim Bilgileri',style: TextStyle( color: colorVal)),
),
],
),
SizedBox(
height:MediaQuery.of(context).size.height,
child: TabBarView(
children: <Widget>[
FutureBuilder(future:resumedata.get(),builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot){
List experiences = List.from(snapshot.data.get('experiences'));
if (snapshot.connectionState == ConnectionState.done){
ListView.builder(
itemCount: experiences.length,
itemBuilder: (context,index){
return Padding(
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
child: Container(
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(20.0)), color: Colors.white, boxShadow: [
BoxShadow(color: Colors.black.withAlpha(100), blurRadius: 5.0),
]),
child: ListTile(
isThreeLine: true,
title: Text('${experiences[index]['position']}'),
subtitle: Text('${experiences[index]['company']} - ${experiences[index]['duration']}'),
),
),
);
});
.....and goes on
and here is the data tree in Firestore
Firestore data tree
You accessed snapshot.data before snapshot.connectionState was done.
Moreover, you forgot to 'return' your list view.
if (snapshot.connectionState == ConnectionState.done) {
List experiences = List.from(snapshot.data.get('experiences')); // This line should be inside if block
return ListView.builder(...); // You forgot to add 'return' here
} ....
This is the code inside your failing code block in your question near the end inside the future builder.

How to scroll a text?

I have a text and I've tried a lot to make it scrollable, what I want is to make the postDesc text scrollable I've tried to wrap it with single child scroll view and listview and expanded but not worked.
please give me a solution
I want to make the screen or the container scrollable or to scroll the text only.
I've seen many solutions but it didn't work for me.
My project has been stopped because of that.
For any details you want please leave a comment.
thanks,
My Code:
#override
Widget build(BuildContext context) {
final userimage = InkWell(
child: Container(
margin: EdgeInsets.only(right: 10.0),
height: 40.0,
width: 40.0,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('${widget.userPhoto}'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(7.0),
),
),
);
final headerDesc = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'${widget.writer}',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
Text(
'25 minutes ago',
style: TextStyle(
color: Colors.grey.withOpacity(0.6),
fontWeight: FontWeight.bold,
),
)
],
);
final header = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[userimage, headerDesc],
);
final descriptionText = Text(
'${widget.postTitle}',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Amiri',
color: Colors.black87,
fontWeight: FontWeight.w600,
fontSize: MediaQuery.of(context).size.width / 20,
),
);
final divider = Divider(
thickness: 0.5,
color: Colors.grey,
);
final footer = Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
onPressed: () {
print(null);
},
icon: Icon(
Icons.share,
color: Theme.of(context).primaryColor,
),
),
Row(
children: <Widget>[
SizedBox(
width: 30.0,
),
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('posts').snapshots(),
builder: (context, snapshot) {
var documents = snapshot.data.documents;
var likes;
for (var document in documents) {
if (document.documentID == widget.uid) {
likes = document['likes'];
}
}
return Text(
'$likes',
);
}),
SizedBox(
width: 3.0,
),
Icon(
Icons.favorite,
color: Colors.red,
),
],
),
],
);
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: MediaQuery.of(context).size.height,
child: Stack(
children: <Widget>[
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImagePreview(
image: widget.networkImage,
),
),
);
},
child: Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(14.0),
child: Container(
height: MediaQuery.of(context).size.height / 5,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14.0),
image: DecorationImage(
image: widget.networkImage.image,
fit: BoxFit.cover,
),
),
),
),
),
Positioned(
top: 90.0,
left: 0.0,
right: 0.0,
child: Padding(
padding: EdgeInsets.only(left: 10.0, right: 10.0),
child: Material(
elevation: 5.0,
shadowColor: Colors.white,
borderRadius: BorderRadius.circular(14.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(14.0),
),
child: Padding(
padding: EdgeInsets.only(
top: 20.0,
bottom: 00.0,
left: 20.0,
right: 20.0,
),
child: ListView(
shrinkWrap: true,
children: <Widget>[
header,
SizedBox(
height: 10.0,
),
descriptionText,
SizedBox(
height: 5,
),
divider,
Padding(
padding: const EdgeInsets.all(20),
child: SingleChildScrollView(
child: Text(
'${widget.postDesc}',
),
),
),
footer,
SizedBox(
height: 10,
),
],
),
),
),
),
),
)
],
),
),
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.red,
child: Icon(
Icons.favorite,
color: Colors.white,
),
onPressed: () async {
await likePost();
},
),
);
}
I might be wrong here, but I think the problem is that you have a SingleChildScrollView inside a ListView. If you just want to scroll the postDesc, you might want to add this to your ListView:
ListView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: [...]
),

How to dynamically arrange cards in a row?

I want to put two cards in a row and have them dynamically resized based on phone size. As seen in the image, the right card has overflow error because the phone dimension is small. Looks fine on a bigger phone.
Ignore the first overflow error
I have tried wrapping the container using Expanded() or Flexible() but it gives an error saying my parent is using a GestureDetector() and it does not allow that.
Widget _showSecondRow(){
return new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new GestureDetector(
child: Card(
elevation: 1,
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Container(
color: Colors.grey.shade200,
padding: EdgeInsets.all(45.0),
child: new Column(
children: <Widget>[
new Icon(Icons.drafts, size: 30.0, color: Colors.black),
new Text("Private\nMessages", textAlign: TextAlign.center, style: TextStyle(color: widget.appModel.getPrimaryTextColor, fontSize: 18.0, fontWeight: FontWeight.bold),)
],
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
)
),
new GestureDetector(
onTap: () => Navigator.push(context, new MaterialPageRoute(builder: (context) =>
new SubscribedScreen()
)),
child: Card(
elevation: 1.0,
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Container(
color: Colors.grey.shade200,
padding: EdgeInsets.all(45.0),
child: new Column(
children: <Widget>[
new Icon(Icons.star, size: 30.0, color: Colors.black),
new Text("Subscribed\nThreads", textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.bold), overflow: TextOverflow.ellipsis,)
],
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
)
),
],
);
}
I expect both cards to be dynamically resized regardless of phone size and fit the width of the phone. Doesnt matter if there's gap in the middle.
Wrap each GestureDetector in Expanded or Flexible

Resources