Search code examples
androidandroid-layoutflutterscrollviewsinglechildscrollview

SingleChildScrollView is not working or I'm doing something wrong


I have a login page with two textField when I have to type keyboard hides login Button and other fields.

Widget build(BuildContext context) {
return Scaffold(
  resizeToAvoidBottomPadding: false,
  body: Container(
    child: SingleChildScrollView(
     //color: Colors.white,
    padding: EdgeInsets.only(top: 120.0, right: 48.0, left: 48.0, bottom: 20.0),
    child: Column(
      children: <Widget>[
        new Image.asset('assets/images/login.png',height: 170, width: 170,),
        SizedBox(height: 40.0,),
        _input("Roll Number",_rollnumberController, false),
        SizedBox(height: 20.0,),
        _input("Phone Number",_phonenumberController, false),
        SizedBox(height: 40.0,),
        buildLogInButton(),
      ],
    ),
  ),
  ),
);
}

Solution

  • 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()
        );
      });
    }