I have changed the solution to using the keyboard visibility to decide when to scroll up or down. I am using a package called flutter_keyboard_visibility.
I have written an example using most of your code, but replacing your specific inputs and login button with generic ones:
Import
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
Class
ScrollController _scrollController = ScrollController();
FocusNode _focusNodePassword = FocusNode();
@override
void initState() {
KeyboardVisibilityNotification().addNewListener(
onChange: (bool visible) {
visible ? scrollToBottom() : scrollToTop();
},
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
controller: _scrollController,
padding: EdgeInsets.only(
top: 120.0, right: 48.0, left: 48.0, bottom: 20.0),
child: Column(
children: <Widget>[
Container(height: 170, width: 170, color: Colors.blue,),
SizedBox(height: 40.0,),
TextFormField(
decoration: InputDecoration(
labelText: 'Email'
),
onEditingComplete: () {
_focusNodePassword.requestFocus();
}
),
SizedBox(height: 20.0,),
TextFormField(
decoration: InputDecoration(
labelText: 'Password'
),
focusNode: _focusNodePassword,
onEditingComplete: () {
FocusScope.of(context).requestFocus(new FocusNode());
}
),
SizedBox(height: 40.0,),
RaisedButton(
child: Text('Login'),
onPressed: () {
_scrollController.animateTo(0,
duration: Duration(milliseconds: 200),
curve: ElasticOutCurve()
);
},
),
],
),
);
}
),
);
}
void scrollToTop() {
Timer(Duration(milliseconds: 50), (){
_scrollController.animateTo(0,
duration: Duration(milliseconds: 400),
curve: ElasticOutCurve()
);
});
}
void scrollToBottom() {
Timer(Duration(milliseconds: 50), (){
_scrollController.animateTo(2000,
duration: Duration(milliseconds: 400),
curve: ElasticOutCurve()
);
});
}