SingleChildScrollView still causes the screen to overflow - flutter

I have a simple screen built using the code shown below. I want to keep the ad banner at the top at all times while the Container() below it to be scrollable. This is the reason I put SingleChildScrollView() in the lower container.
But it still overflows the screen with the following error:
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 162 pixels on the bottom.
This is what the screen looks like:
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
// colorFilter: ColorFilter.mode(Colors.white, BlendMode.color),
image: AssetImage("assets/feathers_bg.jpg"),
fit: BoxFit.cover,
),
),
child: Column(
children: [
AdmobBanner(
//below is test id
adUnitId: 'ca-app-pub-3940256099942544/6300978111',
adSize: AdmobBannerSize.FULL_BANNER,
),
Padding(
padding: const EdgeInsets.all(40.0),
child: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
children: [
Image.network(_birdDetails.thumbnail.source),
SizedBox(height: 10,),
Container(
child: Column(
children: [
Text(
_birdName,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.teal,
fontWeight: FontWeight.bold,
),
),
Text(
_birdDetails.description,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontStyle: FontStyle.italic,
),
),
],
),
),
SizedBox(height: 20,),
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Text(
_birdDetails.extract,
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 16
),
),
),
SizedBox(height: 10,),
],
),
),
),
),
],
),
),

TL;DR version. Your SingleChildScrollView needs to be Expanded (you can put Expanded -> Padding - > SingleChildScrollView).
Longer version you can read in the official documentation, this section describes a similar scenario:
One common reason for this to happen is that the Column has been
placed in another Column (without using Expanded or Flexible around
the inner nested Column). When a Column lays out its non-flex children
(those that have neither Expanded or Flexible around them), it gives
them unbounded constraints so that they can determine their own
dimensions (passing unbounded constraints usually signals to the child
that it should shrink-wrap its contents). The solution in this case is
typically to just wrap the inner column in an Expanded to indicate
that it should take the remaining space of the outer column, rather
than being allowed to take any amount of room it desires.
And here is a bit simplified version of your code that is easily reproducible (to paste and run for example in dartpad):
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'SO Question : 64200763'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
StringBuffer birdDetails;
var rng = new Random();
#override
initState(){
super.initState();
birdDetails = new StringBuffer();
for(int i=0; i<4000; i++){
birdDetails.write(String.fromCharCode(rng.nextInt(25) + 97));
if(rng.nextBool() && rng.nextBool()) birdDetails.write(' ');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
decoration: BoxDecoration(
color: Colors.green[400],
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Column(
children: [
Container(
height: 100,
width: double.maxFinite,
color: Colors.yellow,
child: Text('Ad placeholder', textAlign: TextAlign.center)
),
Expanded(
child: Padding( // Here is your fix, place expanded above the SingleChildScrollView
padding: const EdgeInsets.all(40.0),
child: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
children: [
Image.network('https://picsum.photos/id/1024/512/288'),
SizedBox(height: 10,),
Container(
child: Column(
children: [
Text(
'Bird name',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.teal,
fontWeight: FontWeight.bold,
),
),
Text(
'Bird (random) description',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontStyle: FontStyle.italic,
),
),
],
),
),
SizedBox(height: 20,),
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Text(
birdDetails.toString(),
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 16
),
),
),
SizedBox(height: 10,),
],
),
),
),
),
),
],
),
),
);
}
}
End result (as per how you organized the widgets, but without overflows):
PS, before posting a question I highly recommend stripping / replacing the code of all dependencies that some users might or might not have at hand (like AdMob), unnecessary assets (like AssetImage) and lastly class structures that aren't defined in the question (like birdDetails.thumbnail.source). It might help you debug the problem on your own and if it doesn't it makes it easier for people that are trying to help you ;).

Related

How to center a Row containing wrapped text within a Column

I am having difficulty figuring how to get a Row, which contains wrapped text, to appear centered in a Column.
The issue seems to be that Flexible (or Expanded for that matter) causes the Text widget to consume the entire remaining horizontal space in the Row. This seems fine for text layout purposes, i.e., determining the needed height for the text. However, it also seems to me that is should be possible that once the text has been laid out, the bounds of its widget can be "shrunk" to require only the minimum width necessary. (Notice the difference of width/space within the red bounding box in the images below.)
Is it possible to achieve this in Flutter? What am I overlooking?
I have searched high and low on SO and haven't found this specific question.
The closest related might be this but it's difficult to be certain the way that question was asked. (And it did not receive any answers.)
What I am seeing
What I would like to see
What I have tried
Several permutations of Flexible and Expanded, around the Text, Row, and Column in various combinations
Several different values for fit and flex (with Flexible)
IntrinsicWidth parent on Column
softWrap
Code
(Based on the "Counter" sample from DartPad.)
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent),
),
width: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'\u{1F603}',
style: TextStyle(
fontSize: 24.0,
),
),
Flexible(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
),
child: const Text(
'Some text that ends up taking_two_lines',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
),
],
),
],
),
),
);
}
}
Welp, as I was typing up this question, I discovered the solution, so I may as well write it up for others.
The trick was to use the textWidthBasis argument of Text and set it to TextWidthBasis.longestLine.
If you has parent widget set yours to center too
In my case i set My Colum(mainAlignment to center and it is work for me)
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent),
),
alignment: Alignment.center,
width: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'\u{1F603}',
style: TextStyle(
fontSize: 24.0,
),
),
Flexible(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
),
child: const Text(
'Some text that ends up taking_two_lines',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
),
],
),
],
),
),
Try below code hope its help to you I have try same as your expected design
Your Widget:
Scaffold(
appBar: AppBar(
actions: [
const Center(
child: Padding(
padding: EdgeInsets.all(8),
child: Text(
'Flutter',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(
width: 50,
),
const Text(
'\u{1F603}',
style: TextStyle(
fontSize: 24.0,
),
),
Expanded(
child: const Text(
'Some text that ends up taking_two_lines',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
],
),
],
),
),
Result Screen->

Having trouble in customizing text, text position, fontweight and etc

I'm having trouble customizing the font aspects, and position of my text in the code below. I want to put 'Bula Anvisa', centralized and bold, with a clickable link to its specific documents online. I begin "coding" this app in appinventor, there I had almost everything in order, but with flutter it's being very hard, although I'm loving learning this language. This is my first app and experience with code. After everything is in order, I'd like to make it a beautiful and fluid app. One step at a time.
I'm receiving the message
Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class analgesicos extends StatefulWidget {
const analgesicos({Key? key}) : super(key: key);
#override
State<analgesicos> createState() => _analgesicosState();
}
class _analgesicosState extends State<analgesicos> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.teal,
centerTitle: true,
title: Text('Analgésicos',style: TextStyle(
fontFamily: 'fonts/Quicksand-Light.ttf',
fontSize: 22,
),),
),
body: Container(
constraints: const BoxConstraints(minHeight: 0, maxHeight: 200.0),
child: (
Column(crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(padding: const EdgeInsets.only(top: 10, bottom: 10),),
Container(width: 240.0,
height: 42.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: const Color(0xffc5fce1),
),
child: SizedBox(
child: Text(
'Não-opióides',
style: TextStyle(
fontFamily: 'Quicksand',
fontSize: 18,
color: Colors.black,
height: 1.7,
),
textAlign: TextAlign.center,
),
),
),
Divider(
height: 15),
const Material(
child: (const Card(
child: ListTile(
title: Text('Ácido acetilsalicílico'),
subtitle: Text('''Apresentação: Comprimidos simples de 500 ou 650 mg
Indicação: Antipirético e analgésico.
Posologia odontológica: Uso interno (via oral)
Tomar 1 comprimido de 6/6 horas.'''),
),
)),
),
const Material(
child: (const Card(
color: Colors.white,
child: ListTile(
title: Text('Bula ANVISA'),
),
)),
),
],)
),
),
);
}
}

Flutter: How to prevent screen from scrolling and fit all widgets inside the screen

For some reason everything fits perfectly fine on my device but once using it on a smaller device with screen size 5.5" the screen is scrolling and some of the elements or widgets are outside the screen as shown in the images below. I have listed my code below as well.
How can I prevent this from happening and fit everything inside the screen, regardless the size of the screen?
class OtpVerificationScreen extends StatefulWidget {
const OtpVerificationScreen({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => _OtpVerificationScreen();
}
class _OtpVerificationScreen extends State<OtpVerificationScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
body: SafeArea(
child: Center(
child: Column(
children: [
//Logo
const LogoForAuthScreens(),
const Text(
'Enter verification code',
style: TextStyle(
// fontWeight: FontWeight.bold,
fontSize: 26,
),
),
Container(
margin: const EdgeInsets.only(top: 30, bottom: 20),
child: const Text(
'We send a code to the following number:\n+01723456789',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black45,
),
),
),
Form(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
OtpInputField(),
OtpInputField(),
OtpInputField(),
OtpInputField(),
OtpInputField(),
OtpInputField(),
],
),
),
TextButton(
onPressed: () {},
child: const Text('Resend OTP'),
),
Container(
margin: const EdgeInsets.only(left: 30, top: 30, right: 30),
child: MaterialButton(
onPressed: () {
Navigator.of(context).pushNamed('/signup');
},
color: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
padding:
const EdgeInsets.symmetric(vertical: 20, horizontal: 30),
minWidth: double.infinity,
child: const Text(
'Continue',
style: TextStyle(
color: Colors.white,
),
),
),
),
],
),
),
),
);
}
}
You can wrap each widget inside your column widget with a Flexible widget. This will cause them to resize dynamically based on the available space.

How to add a more than one container in a page layout?

So, I'm really new to flutter or dart. I looked at many tutorials, a bit hard to learn.
I need to know if I can, and how can I add more containers that contain Texts or Button in Flutter.
I am building a login page which has a container for some text and form field. I want to insert a second container where I can insert a button on the bottom of login which says 'GET OTP' has the max width the display offers as shown in the image of Login Page.
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class LoginPage extends StatefulWidget {
#override
LoginPageState createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 180.0,),
Padding(padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Lets Start With Your', style: GoogleFonts.yantramanav(fontSize: 26.0, fontWeight: FontWeight.w300, textStyle: TextStyle(color: Colors.indigo[900])),),
Text('Phone / Email', style: GoogleFonts.robotoCondensed(fontSize: 50.0, fontWeight: FontWeight.w700, textStyle: TextStyle(color: Colors.indigo[900])),),
Padding(padding: EdgeInsets.only(top: 20.0),
child: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Enter phone number/email id',
hintText: 'Enter phone number/email id',
)
),
Padding(
padding: EdgeInsets.only(top: 170.0),
child: Center(
child: Column(children: <Widget>[
OutlineButton(onPressed: () {}, child: Text('Skip Login', style: TextStyle(color: Colors.grey[500] ),),
borderSide: BorderSide( color: Colors.grey[300], width: 2.0,),
),
],),), ) ,
],
)
)
]
)
),
**# I want to add a container (to insert a button with full width of the display) here**
],)
);
}
}
One of the solutions is to use the Stack widget, that gives you great freedom to position widgets:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(...), //your first container
Positioned( //used to position the given child
bottom: 0,
child: GestureDetector(
onTap: () {
//here what you want to do when the user press the button
},
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(10),
width: MediaQuery.of(context).size.width, //to give the container the width of the screen
child: Text(
'GET OTP',
style: TextStyle(
color: Colors.white,
fontSize: 22,
),
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.purple,
Colors.blue, //Linear Gradient with 3 colors
Colors.blue[800],
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
),
),
),
],
),
);
}
The result:

Expand widget to match parent height inside the row in flutter

I want to create below UI
How to draw a line between widget, If try to expand the column line inside the row it gives error of infinity height
//Below some code not able to post all the code.
ListView(
shrinkWrap: true,
children: <Widget>[
new _Row(
label: "1",
body:
"Screening: We will screen your current portfolio to check your Portfolio's health.",
),
SizedBox(
height: 16,
),
],
),
class _Row extends StatelessWidget {
final String label;
final String body;
const _Row({Key key, this.label, this.body});
#override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 28,
height: 28,
decoration: BoxDecoration(
color: Color(0xff76587b).withOpacity(0.5),
shape: BoxShape.circle,
),
child: Center(
child: Text(
label,
textAlign: TextAlign.start,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500),
),
),
),
SizedBox(
width: 16,
),
Flexible(
child: Text(
body,
style: kModelTargetCARGTInactiveTextLabel.copyWith(
color: Colors.black, height: 1.4),
),
),
],
);
}
}
In this code line between bullet points not visible. I tried may option but it not working.