I\'m building a flutter app with a Login Screen. On focus on the text field(s), the screen is overflowed and i cannot scroll. I\'ve tried using a ListView.builder
The ListView
solution should work, but at the time of writing, it suffers from the crash listed here. Another way to achieve the same thing without this crash is to use a SingleChildScrollView
:
return new Container(
child: new SingleChildScrollView(
child: new Column(
children: <Widget>[
_showChild1(),
_showChild2(),
...
_showChildN()
]
)
)
);
There are two easy ways of doing it.
Wrap your Column
in a SingleChildScrollView
SingleChildScrollView(
child: Column(
children: [
Text('First'),
//... other children
Text('Last'),
],
),
)
Use ListView
instead of Column
.
ListView(
children: [
Text('First'),
//... other children
Text('Last'),
],
)
This approach is simple to use, but you lose features like crossAxisAlignment
and other benefits provided by Column
, in that case, you can wrap your children widget inside Align
and set alignment property.
Now you may have nested children which are further scrollable, in that case, you need to provide a fixed height to your children, you may use SizedBox
for that, that's it.
For example:
ListView(
children: [
Text('First'),
SizedBox(
height: 100,
child: ListView(...), // nested ScrollView
),
Text('Last'),
],
)
Using SingleChildScrollView
with Columns
make your screen scrollable, and you can make your layout as above
Here is how can you do it
class MyHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
bottom: false,
child: Container(
padding: EdgeInsets.only(left: 15, right: 15),
height: double.infinity,
width: double.infinity,
child: SingleChildScrollView(
padding: EdgeInsets.only(bottom: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 200.0,
),
Card(
elevation: 8.0,
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.person),
labelText: "Username or Email",
),
),
SizedBox(
height: 15.0,
),
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
labelText: "Password",
),
),
SizedBox(
height: 30.0,
),
MaterialButton(
height: 50.0,
elevation: 5,
minWidth: 300,
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: Theme.of(context).primaryColor,
disabledColor: Theme.of(context)
.primaryColor
.withOpacity(0.50),
disabledElevation: 0,
child: Text('SIGN IN',
textAlign: TextAlign.center, style: TextStyle(color: Colors.white),))
],
),
),
),
SizedBox(
height: 25.0,
),
Row(
children: <Widget>[
Expanded(child: Text("Don't Have a Account?")),
Text("Sign Up",
style: TextStyle(
color: Colors.blue,
)),
],
),
SizedBox(
height: 50.0,
),
Align(
alignment: Alignment.bottomCenter,
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Text(
'New to App?',
style: TextStyle(color: Colors.black87),
),
SizedBox(
width: 5,
),
GestureDetector(
onTap: () {
},
child: Text(
"REGISTER", style: TextStyle(
color: Colors.blue,
)
),
),
]),
)
],
)),
),
));
}
}
Wrap your column in SingleChildScrollView and then wrap SingleChildScrollView in a Center widget to center the widgets in the column.
Center(
child: SingleChildScrollView(
child: Column(
children: [
Text('First'),
//... other children
Text('Last'),
],
),
)
try this Code: Its Using ListView
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.all(15.0),
children: <Widget>[
Center(
child: Card(
elevation: 8.0,
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.person),
labelText: "Username or Email",
),
),
SizedBox(
height: 15.0,
),
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
labelText: "Password",
),
),
SizedBox(
height: 15.0,
),
Material(
borderRadius: BorderRadius.circular(30.0),
//elevation: 5.0,
child: MaterialButton(
onPressed: () => {},
minWidth: 150.0,
height: 50.0,
color: Color(0xFF179CDF),
child: Text(
"LOGIN",
style: TextStyle(
fontSize: 16.0,
color: Colors.white,
),
),
),
)
],
),
),
),
),
SizedBox(
height: 25.0,
),
Row(
children: <Widget>[
Expanded(child: Text("Don't Have a Account?")),
Text("Sign Up",
style: TextStyle(
color: Colors.blue,
)),
],
),
],
),
),
bottomNavigationBar: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: RaisedButton(
padding: EdgeInsets.all(15.0),
onPressed: () {},
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
32.0,
),
side: BorderSide(color: Color(0xFF179CDF))),
child: Text(
"SKIP SIGN UP FOR NOW",
style:
TextStyle(fontSize: 18.0, color: Color(0xFF179CDF)),
),
)),
],
),
),
);
}
}