Let widgets be moved 'above' the screen when opening on screen keyboard

Issue

I’m experimenting with a login page for flutter. At the moment it looks like so:

Before open keyboard

When I attempt to type into one of the text fields using the on-screen keyboard, flutter attempts to move all my content up until the image showing "TEST" reaches the top and the bottom content overflows:

After open keyboard

Other apps I’ve seen allow the content to continue moving "above" the screen, and doesn’t just stop once the top widget hits the top of the screen.

I know I can disable the resizing and movement of these widgets in the scaffold by setting resizeToAvoidBottomInset to false however this doesn’t really look too great and will cover different amounts depending on the keyboard so I’d rather not do this.

How can I go about allowing the widgets to continue moving up? Also, would there be a way to stop the "Create Account" widget only from moving like the rest and keep it underneath the keyboard? I’ve tried looking in flutter’s documentation but I don’t really know how to describe this problem in a way to obtain useful results as I’m still quite new to flutter.

The "Create Account" button is anchored to the bottom of the screen in its own column, and the rest of the widgets are in an expanded widget containing another column. Both these columns are encased by a parent column.
Here is my widget tree, in case it is useful:

  @override
  Widget build(BuildContext context) {

    return new WillPopScope(
      onWillPop: () async => false,
      child: Scaffold(
        backgroundColor: Colors.white,
        body: Column(children: <Widget>[
          Expanded(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Image.asset(
                  "lib/assets/test.png",
                  height: 20.h,
                  width: 20.h,
                ),
                SizedBox(height: 10.h),
                Text(
                  "Login:",
                  style: TextStyle(
                    fontSize: 16.sp,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 1.5.h),
                RoundedInputField(
                  editTextBackgroundColor: Colors.blue[300],
                  hintText: "Email:",
                  autoFocus: false,
                  onChanged: (value) {
                    
                  },
                ),
                RoundedPasswordField(
                  editTextBackgroundColor: Colors.blue[300],
                  onChanged: (value) {
                    
                  },
                  onSubmitted: (value) {
                    
                  },
                ),
                SizedBox(height: 0.75.h),
                Text(
                  "$errMsg",
                  style: TextStyle(
                    fontSize: 13.sp,
                    fontWeight: FontWeight.normal,
                    color: Colors.red,
                  ),
                ),
                SizedBox(height: 0.75.h),
                RoundedButton(
                  text: "Login!",
                  height: 6.h,
                  color: Colors.blue,
                  textColor: Colors.white,
                  press: () {
                    
                  },
                ),
              ],
            ),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.end,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Align(
                alignment: Alignment.bottomCenter,
                child: ElevatedButton(
                  style: ElevatedButton.styleFrom(primary: Colors.blue, textStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.bold), fixedSize: Size(100.w, 10.h),),
                  child: Text("Create Account"),
                  onPressed: () {
                    
                    }
                  },
                ),
              ),
            ],
          ),
        ]),
      ),
    );

If anybody could help it would be greatly appreciated.

Solution

You should wrap your body with SingleChildScrollView:

example:

@override
  Widget build(BuildContext context) {

    return new WillPopScope(
      onWillPop: () async => false,
      child: Scaffold(
        backgroundColor: Colors.white,
        body: Container(
        child: SingleChildScrollView(
        child: Column(...)
        ),
       ),
      ),
    );

Answered By – Sandeep Sharma

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *