Overflow Error in Flutter when keyboard open - dart

I am designing a login page it overflowed when I click on any text form field it open keyboard and through overflow warning like this see attached image.
I also want a Raised button icon should be on the right side of the button.
Widget build(BuildContext context) {
return Container(
child: Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/login_page_bg_1.jpg'),
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.55), BlendMode.dstATop))),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
margin: new EdgeInsets.only(top: 42.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset('assets/logo.png',
width: 250.0, height: 200.21),
],
),
),
),
Expanded(
flex: 2,
child: Container(
margin: new EdgeInsets.only(bottom: 40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//form filed goes here
Text('Login As User',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 35.0)),
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
hintText: 'you#example.com',
labelText: 'Email Address',
),
new Container(
// width: MediaQuery.of(context).size.width,
child: RaisedButton.icon(
color: Color.fromARGB(251, 188, 74, 1),
label: Text('LOGIN'),
icon: Icon(Icons.send,
size: 10.0, color: Colors.black),
onPressed: () {
this.submit();
}, ),)],),),)],)],),),);
Intital state
Error/overflowed State

Set following property to false
Scaffold(
resizeToAvoidBottomInset: false,
...
)
If you're having issues with overflow error, use SingleChildScrollView with it.
Scaffold(
resizeToAvoidBottomInset: false, // set it to false
body: SingleChildScrollView(child: YourBody()),
)
PS: If you like to scroll your widget when the keyboard opens, you can take a look at this answer

This is happening because when the keyboard comes on screen, the height of the canvas to draw decreases. One solution is to wrap your root container inside SingleChildScrollView like this :
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Stack(
fit: StackFit.loose,
children: <Widget>[
Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/login_page_bg_1.jpg'),
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.55), BlendMode.dstATop)
)
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 42,),
Expanded(
flex: 1,
child: Center(
child:
Image.asset('assets/logo.png',
width: 250.0, height: 200.21),
),
),
Expanded(
flex: 2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//form filed goes here
Text('Login As User',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 35.0)),
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
hintText: 'you#example.com',
labelText: 'Email Address',
)
),
new Container(
// width: MediaQuery.of(context).size.width,
child: RaisedButton.icon(
color: Color.fromARGB(251, 188, 74, 1),
label: Text('LOGIN'),
icon: Icon(Icons.send,
size: 10.0, color: Colors.black),
onPressed: () {
//this.submit();
}, ),)],)),
SizedBox(height: 40,)
],)],),));
It will make your screen scrollable when the height of the content gets more than the available height of the viewport.

A much simpler solution (source) seems to be just setting the Scaffold property resizeToAvoidBottomPadding to false.
This works great with me:
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(...),
body: ...

Add resizeToAvoidBottomPadding: false, and resizeToAvoidBottomInset: false,
to your Scaffold widget.
Wrap your code with a Container, set the Container's parameters height: MediaQuery.of(context).size.height, and width: MediaQuery.of(context).size.width,. Then wrap your Container with a SingleChildScrollView.

Setting resizeToAvoidBottomInset: true and using body: ListView() works as well. This enables you to scroll the page when you open the keyboard.

An even easier version is to just wrap the offending container with a ListView widget. It makes the screen scrollable and is simple to implement. You can use multiple children with this widget.
Scaffold(
body: ListView(
children: <Widget> [
Container(
),
TextView(
),
Column(
),
],
),
)

you should make the scaffold's floating widgets should size themselves to avoid the onscreen keyboard using :
Scaffold(
resizeToAvoidBottomInset: false,
...
)

Related

Flutter - Swipe down to start Navigator.pop animation

I want to know how to swipe down on a page to start the pop animation, but I want the animation to play as we're swiping down. For exemple, the "swipe from left to right" on iOS to pop a page is amazing, because the page that will pop follows the finger swiping LTR. And I want to do the same but vertically, and we would be able to close it from anywhere in the scaffold (not necessarily from the top edge). My animation has an hero animation so it might be harder.
Here's how it looks now :
And I want to have this animation playing, but swiping down, not swiping from the left. (Like exactly this animation, or one where the page goes down).
Here is the page I want to swipe to close :
class TreeDescription extends StatelessWidget {
Tree tree;
bool goBackArrow;
TreeDescription(this.tree, {this.goBackArrow = true});
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onVerticalDragStart: (details) => print("Do something"),
child: Column(
children: <Widget>[
Stack(
children: [
Hero(
transitionOnUserGestures: true,
tag: tree.imagePath,
child: Container(
height: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.black, Colors.transparent],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
stops: [0, 0.2]
),
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
image: DecorationImage(image: AssetImage(tree.imagePath), fit: BoxFit.cover),
),
child: Align(
alignment: Alignment.bottomCenter,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
tree.name,
style: Theme.of(context)
.textTheme
.headline4
.copyWith(fontWeight: FontWeight.w600, color: Colors.white),
),
Text(
tree.species,
style: Theme.of(context)
.textTheme
.headline6
.copyWith(fontWeight: FontWeight.w600, color: Colors.white),
),
],
),
),
),
),
goBackArrow ? Positioned(
top: 30,
child: IconButton(
icon: Icon(Icons.chevron_left, color: Colors.white, size: 40,),
onPressed: () => Navigator.pop(context),
tooltip: 'Retour',
),
) : SizedBox.shrink()
],
),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Description :", style: Theme.of(context).textTheme.headline6.copyWith(color: Theme.of(context).primaryColor),),
Text(tree.description, textAlign: TextAlign.justify,),
SizedBox(height: 20,),
Text("La feuille du ${tree.name.toLowerCase()} :", style: Theme.of(context).textTheme.headline6.copyWith(color: Theme.of(context).primaryColor),),
SizedBox(height: 5,),
Row(
children: [
Container(
width: MediaQuery.of(context).size.width/2-40,
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset(tree.leafImagePath)
),
),
SizedBox(width: 5,),
Expanded(
child: Text(tree.leafDescription, textAlign: TextAlign.justify,)
),
],
),
],
),
),
),
)
],
),
),
);
}
}

How to implement boxes that fill the screen & I dont see my drawer

I'm trying to implement a UI design, something like this:
And that's what I've achieved so far:
I got stuck in the stage of filling the screen with boxes, I tried to implement this in multiple ways(expanded, containers etc), but the result didn't satisfy me.
How do i implement this?
And I also have another problem, when i create the drawer it work(i can scroll the screen to the right and the drawer navigation screen appears), But i can't see the drawer icon.
By the way, if you have suggestions for improving the code or things I could write better i'll be glad to hear that
My code:
class Sample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(),
body: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 2,
width: double.infinity,
color: Color.fromRGBO(50, 50, 205, 1),
),
Opacity(
child: Image.network(
'https://cdn.pixabay.com/photo/2015/04/23/21/36/auto-736794__340.jpg',
//half of the screen
height: MediaQuery.of(context).size.height / 2,
fit: BoxFit.cover,
),
opacity: 0.3,
),
SafeArea(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 58.0),
child: Text(
'Parking App',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
),
],
),
),
],
),
],
),
);
}
}
There might be better ways to achieve this, but here's the solution with rows and columns:
import 'package:flutter/material.dart';
class SamplePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
body: Column(
children: <Widget>[
Image.network(
"http://i63.tinypic.com/16p2xu.jpg",
fit: BoxFit.cover,
height: screenHeight / 2,
),
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.account_balance),
SizedBox(height: 10),
Text("My Stats"),
],
),
),
Expanded(
child: Container(
color: Colors.indigo,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Icon(Icons.accessibility, color: Colors.white),
SizedBox(height: 10),
Center(
child: Text(
"Component",
style: TextStyle(color: Colors.white),
),
)
],
),
),
),
],
),
),
Expanded(
child: Container(
color: Colors.cyanAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.access_alarm),
SizedBox(height: 20),
Text("Workout"),
],
),
),
),
],
),
),
],
),
);
}
}
Result:
you can achieve similar layout using stack. i demonstrated as below.
Note: make sure that you are using full screen with content otherwise black screen will be there.
class Sample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 2,
width: double.infinity,
decoration: BoxDecoration(
color: Color.fromRGBO(50, 50, 205, 0.3),
image: DecorationImage(
image: NetworkImage(
'https://cdn.pixabay.com/photo/2015/04/23/21/36/auto-736794__340.jpg',
),
fit: BoxFit.cover,
),
),
),
],
),
Scaffold(
backgroundColor: Colors.transparent,
drawer: Drawer(),
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
title: new Text("Demo"),
centerTitle: true,
),
body: Column(
children: <Widget>[
Expanded(
child: Center(
child: new Container(
decoration: BoxDecoration(
color: Colors.red
),
child: new Text("book"),
),
),
)
],
),
),
],
);
}
}

Card width match with parent : flutter

I am new in Flutter so I want to know that how can I set a width to match parent layout width
new Scaffold(
body: new Container(
decoration: new BoxDecoration(color: AppColors.hoBlue),
child: Padding(
padding: EdgeInsets.all(20.0),
child: new Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Stack(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.all(20.0),
child: Card(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0.0, 20.0,20.0),
child: Column(
children: <Widget>[
Card(
elevation: 10.0,
child: Padding(
padding: EdgeInsets.all(20.0),
child:
Text("Sign Up Here"),
),
),
TextField(
decoration: InputDecoration(
labelText: "Email",
hintText: "example#mail.com",
),
autofocus: true,
),
TextField(
decoration: InputDecoration(
labelText: "Password",
),
autofocus: true,
),
SizedBox(
width: double.infinity,
// height: double.infinity,
child: new RaisedButton(
color: AppColors.hoBlue,
child: Text(
"Sign In",
style: TextStyle(
color: Colors.white,
fontFamily: 'Raleway',
fontSize: 22.0,
),
),
onPressed: () => print('Sign In'),
),
)
],
)),
),
),
),
],
)
],
),
],
)),
),
));
Result From Code Above
i need help to make card stack with parent like
Result I want
i already try with using stack but the result card parent card overlaping the first card.
I know about little bit on Expanded tag but Expanded expand view to both direction, i dont know how to do it. Help me if you know, Thanks in Advance.
You don't need Stack to get that view - it can be done using Column & Material widget.
return Scaffold(
body: new Container(
decoration: new BoxDecoration(color: Colors.blue),
child: new Center(
child: MergeSemantics(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Material(
elevation: 24.0,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text("Sign Up Here"),
),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 10.0, 20.0, 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: "Email",
hintText: "example#mail.com",
),
autofocus: true,
),
TextField(
decoration: InputDecoration(
labelText: "Password",
),
autofocus: true,
),
SizedBox(
width: double.infinity,
// height: double.infinity,
child: new RaisedButton(
color: Colors.blue,
child: Text(
"Sign In",
style: TextStyle(
color: Colors.white,
fontFamily: 'Raleway',
fontSize: 22.0,
),
),
onPressed: () => print('Sign In'),
),
)
],
)),
],
),
),
],
),
),
)),
));
Output:
If you want to resize or alter the card view Then just put Card inside the Container view then adjust your container size.
This link will help you :https://stackoverflow.com/a/50017126/7418129
Just Put Card in Container
Padding(
padding: EdgeInsets.all(20),
child: Container(
height: 50,
width: double.infinity,
child: Card(
child: Align(
alignment: Alignment.centerLeft,
child: Text("Edit Profile")),
),
),
)
Use Material widget that will use as same as card do...and take always a full width and height as same as its parent class...

flutter all widgets on screen hides when keyboard appears

I am using TabBar and a custom searchview, when I click inside TextField to search and keyboard pops up my all view hides, am attaching screenshots below. Is this flutter issue or I am doing wrong in my code. Please have a look at my code. without popping up keyboard my this is working fine.
return new Scaffold(
body: new Container(
// margin: EdgeInsets.all(10.0),
//color: Colors.white30,
child: new Column(
children: <Widget>[
new Container(
height: 70.0,
color: Theme.of(context).primaryColor,
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 3.0),
child: new Icon(Icons.search),
),
new Container(
width: MediaQuery.of(context).size.width - 100.0,
// Subtract sums of paddings and margins from actual width
child: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search', border: InputBorder.none),
// onChanged: onSearchTextChanged,
),
),
new IconButton(icon: new Icon(Icons.cancel), onPressed: () {
controller.clear();
// onSearchTextChanged('');
FocusScope.of(context).requestFocus(new FocusNode());
},),
],
),
)
))),
new Flexible(
child: new ListView.builder(
itemCount: productList == null ? 0 : productList.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Column(
children: <Widget>[
new Container(
margin: EdgeInsets.all(10.0),
child: new Column(
children: <Widget>[
new Column(
children: <Widget>[
new Padding(padding: const EdgeInsets.only(top: 5.0)),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Container(
alignment: FractionalOffset.topLeft ,
width: 250.0,
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Text(productList[index].name,
style: new TextStyle(color: Colors.black,
fontSize: 18.0, fontWeight: FontWeight.bold),
)
],
),
),
new Text("£"+productList[index].price.toString(),
style: new TextStyle(color: Colors.black,
fontSize: 18.0, fontWeight: FontWeight.bold
),),
],
)
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Flexible(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start ,
children: <Widget>[
new Text(
productList[index].description,
overflow: TextOverflow.fade ,),
],
))
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new ListTileItemAddRemove(productList[index]),
new Padding(padding: EdgeInsets.only(bottom: 10.0))
],
)
],
),
),
new Divider(color: Colors.black,)
],
),
);
}),
),
],
)
),
);
when I click inside TextField all widgets disappears. please see below.
I think flutter widgets are resized when keyboard pops up, I've resolved this issue by setting value false of resizeToAvoidBottomPadding inside Scaffold. Issue has been resolved but still I am looking for the reason behind this issue.
return new Scaffold(
resizeToAvoidBottomPadding : false,
body: new Container(
-
-
-
-
}

Flutter align button to bottom of Drawer

I'm trying to have a Widget align to the bottom of my NavDrawer while still keeping a DrawerHeader and a list at the top of the Drawer. Here's what I'm trying:
drawer: new Drawer(
child: new Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Text('Top'),
new Align(
alignment: FractionalOffset.bottomCenter,
child: new Text('Bottom'),
),
],
),
),
The bottom text should be aligned to the bottom of the drawer, but It isn't!
You need to wrap your Align widget in Expanded.
drawer: Drawer(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('Top'),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Text('Bottom'),
),
),
],
),
),
Edit:
Years on and there's a much easier solution:
return Drawer(
child: Column(
children: [
ListView(), // <-- Whatever actual content you want goes here
Spacer(), // <-- This will fill up any free-space
// Everything from here down is bottom aligned in the drawer
Divider(),
ListTile(
title: Text('Settings'),
leading: Icon(Icons.settings),
),
ListTile(
title: Text('Help and Feedback'),
leading: Icon(Icons.help),
),
]
);
A little late to the party, but here's my solution to this problem:
#override
Widget build(BuildContext context) {
return Drawer(
// column holds all the widgets in the drawer
child: Column(
children: <Widget>[
Expanded(
// ListView contains a group of widgets that scroll inside the drawer
child: ListView(
children: <Widget>[
UserAccountsDrawerHeader(),
Text('In list view'),
Text('In list view too'),
],
),
),
// This container holds the align
Container(
// This align moves the children to the bottom
child: Align(
alignment: FractionalOffset.bottomCenter,
// This container holds all the children that will be aligned
// on the bottom and should not scroll with the above ListView
child: Container(
child: Column(
children: <Widget>[
Divider(),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings')),
ListTile(
leading: Icon(Icons.help),
title: Text('Help and Feedback'))
],
)
)
)
)
],
),
);
}
This produces the below output where the UserAccountDrawerHeader and the text items can be scrolled around inside the drawer but the Divider and the two ListTiles stay static on the bottom of the drawer.
look whats the problem with your code you have added a Column as a Child to the Drawer so whatever you add in it are vertically placed and The height of Column is by default shrunk to its children's height and it gets larger as the child gets, so there's no point in adding an Align inside a Column
The Simpler Solution Would be to use an Expanded Widget that takes the remaining Space Look I have used a Column and added A widget above and below the Expanded Widget.
Drawer(
elevation: 1.5,
child: Column(children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.redAccent,
)),
Expanded(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
ListTile(
title: Text('My Cart'),
leading: Icon(Icons.shopping_cart),
onTap: () {},
),
ListTile(
title: Text('My Orders'),
leading: Icon(Icons.add_shopping_cart),
onTap: () {},
),
ListTile(
title: Text('Logout'),
leading: Icon(Icons.exit_to_app),
onTap: () {})
],
)),
Container(
color: Colors.black,
width: double.infinity,
height: 0.1,
),
Container(
padding: EdgeInsets.all(10),
height: 100,
child: Text("V1.0.0",style: TextStyle(fontWeight: FontWeight.bold),)),
])),
A simple approach would be to use Spacer() like:
Scaffold(
drawer: Drawer(
child: Column(
children: <Widget>[
Text('Top'),
Spacer(), // use this
Text('Bottom'),
],
),
)
)
here is my solution of a vertical Row with icons in the end of the drawer.
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
Expanded(
child: ListView(
children: <Widget>[
DrawerHeader(
padding: const EdgeInsets.all(7),
decoration: BoxDecoration(
color: AppColors.menuHeaderColor,
),
child: buildHeader(),
),
AccountDrawerRow(),
ListTile(
leading: Icon(Icons.directions_car),
title: Text(translations.button.vehicles),
),
ListTile(
leading: Icon(Icons.calendar_today),
title: Text(translations.button.appointments,),
),
],
),
),
Container(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Container(
padding: EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
InkWell(
onTap: () => Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SettingsPage())),
child: Icon(Icons.settings)),
Icon(Icons.help),
Icon(Icons.info),
],
),
),
),
),
],
),
);
}
I'd put it in a row and align all the stuff to bottom using crossAxisAlignment: CrossAxisAlignment.baseline
Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.baseline,
children: <Widget>[
Text(
'12.00',
style: Theme.of(context).textTheme.headline2,
textAlign: TextAlign.start,
),
Text(
'USD',
style: Theme.of(context).textTheme.bodyText2,
textAlign: TextAlign.start,
),
]),
Using Expanded widget to align widget to bottom of column parent widget
Column(
children: [
..other children
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Text(
'Button',
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: 18,
color: Colors.black),
),
),
),
],
),

Resources