I have the following screen and I need the image area to be fixed and the form part to be scrollable when the keyboard opens:

Collapsed keyboard view Expanded keyboard view

Why the scrolling isn't working for the form part? I tried both with ListView and SingleChildScrollView, but it only works if I wrap the entire content (image and form) with it.

import 'package:ahgora/models/user.dart';
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final _user = User();
  final _formKey = GlobalKey<FormState>();
  final _tokenNode = FocusNode();
  final _userNode = FocusNode();
  final _passwordNode = FocusNode();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Builder(
          builder: (context) => Form(
            key: _formKey,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Container(
                  child: Image.asset("assets/images/logo.jpg",
                      fit: BoxFit.scaleDown,
                      width: 160,
                      alignment: Alignment.center),
                  margin: EdgeInsets.only(top: 100.0),
                ),
                ListView(shrinkWrap: true, children: <Widget>[
                      Container(
                        margin: EdgeInsets.all(20.0),
                        child: TextFormField(
                          textInputAction: TextInputAction.next,
                          focusNode: _tokenNode,
                          onFieldSubmitted: (term) {
                            _fieldFocusChange(context, _tokenNode, _userNode);
                          },
                          decoration: InputDecoration(
                            border: OutlineInputBorder(),
                            labelText: 'Chave ',
                          ),
                        ),
                      ),
                      Container(
                        margin: EdgeInsets.all(20.0),
                        child: TextFormField(
                          textInputAction: TextInputAction.next,
                          focusNode: _userNode,
                          onFieldSubmitted: (term) {
                            _fieldFocusChange(
                                context, _userNode, _passwordNode);
                          },
                          decoration: InputDecoration(
                              border: OutlineInputBorder(),
                              labelText: 'Usuário'),
                        ),
                      ),
                      Container(
                        margin: EdgeInsets.all(20.0),
                        child: TextFormField(
                          textInputAction: TextInputAction.next,
                          focusNode: _passwordNode,
                          decoration: InputDecoration(
                              border: OutlineInputBorder(), labelText: 'Senha'),
                        ),
                      ),
                      Container(
                        margin: EdgeInsets.all(20.0),
                        child: MaterialButton(
                          color: Colors.redAccent,
                          textColor: Colors.white,
                          onPressed: () => {},
                          child: Text('Registrar'),
                        ),
                      )
                    ]),
              ],
            ),
          ),
        ),
      ),
    );
  }

  _fieldFocusChange(
      BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
    currentFocus.unfocus();
    FocusScope.of(context).requestFocus(nextFocus);
  }
}


Solution 1: Hardik Kumbhani

You just have to wrap up your column with SingleChildScrollView Widget and you will get your soultion.

SingleChildScrollView(child: Column( children: <Widget>[]))


Solution 2: Amit Prajapati

I made small change, if feasible please try this.

        class Home extends StatefulWidget {
        @override
        _HomeState createState() => _HomeState();
        }

        class _HomeState extends State<Home> {

        final _formKey = GlobalKey<FormState>();
        final _tokenNode = FocusNode();
        final _userNode = FocusNode();
        final _passwordNode = FocusNode();

        @override
        Widget build(BuildContext context) {
            return Scaffold(
            resizeToAvoidBottomInset: true,
            body: Container(
                child: Builder(
                builder: (context) => Form(
                    key: _formKey,
                    child: SingleChildScrollView(
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                        Container(
                            child: Image.network("http://www.militaryzone.eu/www/ir/produkt-images/108561-image0--mm344x300.jpg",
                                fit: BoxFit.scaleDown,
                                width: 160,
                                alignment: Alignment.center),
                            margin: EdgeInsets.only(top: 100.0),
                        ),

                            Container(
                            margin: EdgeInsets.all(20.0),
                            child: TextFormField(
                                textInputAction: TextInputAction.next,
                                focusNode: _tokenNode,
                                onFieldSubmitted: (term) {
                                _fieldFocusChange(context, _tokenNode, _userNode);
                                },
                                decoration: InputDecoration(
                                border: OutlineInputBorder(),
                                labelText: 'Chave ',
                                ),
                            ),
                            ),
                            Container(
                            margin: EdgeInsets.all(20.0),
                            child: TextFormField(
                                textInputAction: TextInputAction.next,
                                focusNode: _userNode,
                                onFieldSubmitted: (term) {
                                _fieldFocusChange(
                                    context, _userNode, _passwordNode);
                                },
                                decoration: InputDecoration(
                                    border: OutlineInputBorder(),
                                    labelText: 'Usuário'),
                            ),
                            ),
                            Container(
                            margin: EdgeInsets.all(20.0),
                            child: TextFormField(
                                textInputAction: TextInputAction.next,
                                focusNode: _passwordNode,
                                decoration: InputDecoration(
                                    border: OutlineInputBorder(), labelText: 'Senha'),
                            ),
                            ),
                            Container(
                            margin: EdgeInsets.all(20.0),
                            child: MaterialButton(
                                color: Colors.redAccent,
                                textColor: Colors.white,
                                onPressed: () => {},
                                child: Text('Registrar'),
                            ),
                            )

                        ],
                    ),
                    ),
                ),
                ),
            ),
            );
        }

        _fieldFocusChange(
            BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
            currentFocus.unfocus();
            FocusScope.of(context).requestFocus(nextFocus);
        }
        }

enter image description here

Second approach with Expand

    class _HomeState extends State<Home> {

    final _formKey = GlobalKey<FormState>();
    final _tokenNode = FocusNode();
    final _userNode = FocusNode();
    final _passwordNode = FocusNode();

    @override
    Widget build(BuildContext context) {
        return Scaffold(
        resizeToAvoidBottomInset: true,
        body: Container(
            child: Builder(
            builder: (context) => Form(
                key: _formKey,
                child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                    Container(
                    child: Image.network("http://www.militaryzone.eu/www/ir/produkt-images/108561-image0--mm344x300.jpg",
                        fit: BoxFit.scaleDown,
                        width: 160,
                        alignment: Alignment.center),
                    margin: EdgeInsets.only(top: 100.0),
                    ),
                    Expanded(
                    child: ListView(shrinkWrap: true, children: <Widget>[
                        Container(
                        margin: EdgeInsets.all(20.0),
                        child: TextFormField(
                            textInputAction: TextInputAction.next,
                            focusNode: _tokenNode,
                            onFieldSubmitted: (term) {
                            _fieldFocusChange(context, _tokenNode, _userNode);
                            },
                            decoration: InputDecoration(
                            border: OutlineInputBorder(),
                            labelText: 'Chave ',
                            ),
                        ),
                        ),
                        Container(
                        margin: EdgeInsets.all(20.0),
                        child: TextFormField(
                            textInputAction: TextInputAction.next,
                            focusNode: _userNode,
                            onFieldSubmitted: (term) {
                            _fieldFocusChange(
                                context, _userNode, _passwordNode);
                            },
                            decoration: InputDecoration(
                                border: OutlineInputBorder(),
                                labelText: 'Usuário'),
                        ),
                        ),
                        Container(
                        margin: EdgeInsets.all(20.0),
                        child: TextFormField(
                            textInputAction: TextInputAction.next,
                            focusNode: _passwordNode,
                            decoration: InputDecoration(
                                border: OutlineInputBorder(), labelText: 'Senha'),
                        ),
                        ),
                        Container(
                        margin: EdgeInsets.all(20.0),
                        child: MaterialButton(
                            color: Colors.redAccent,
                            textColor: Colors.white,
                            onPressed: () => {},
                            child: Text('Registrar'),
                        ),
                        )
                    ]),
                    ),
                ],
                ),
            ),
            ),
        ),
        );
    }

    _fieldFocusChange(
        BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
        currentFocus.unfocus();
        FocusScope.of(context).requestFocus(nextFocus);
    }
    }

enter image description here


Solution 3: Kothai

// If you need to scroll only the form part,

then simply wrap your ListView widget with Flexible widget.

  Scaffold(
  body: Container(
    child: Builder(
      builder: (context) => Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Container(
              child: Image.network(
                  "https://buildflutter.com/wp-content/uploads/2018/04/buildflutter_255.png",
                  fit: BoxFit.scaleDown,
                  width: 160,
                  alignment: Alignment.center),
              margin: EdgeInsets.only(top: 100.0),
            ),
            Flexible(
              child: ListView(shrinkWrap: true, children: <Widget>[
                Container(
                  margin: EdgeInsets.all(20.0),
                  child: TextFormField(
                    textInputAction: TextInputAction.next,
                    focusNode: _tokenNode,
                    onFieldSubmitted: (term) {
                      _fieldFocusChange(context, _tokenNode, _userNode);
                    },
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Chave ',
                    ),
                  ),
                ),
                Container(
                  margin: EdgeInsets.all(20.0),
                  child: TextFormField(
                    textInputAction: TextInputAction.next,
                    focusNode: _userNode,
                    onFieldSubmitted: (term) {
                      _fieldFocusChange(context, _userNode, _passwordNode);
                    },
                    decoration: InputDecoration(
                        border: OutlineInputBorder(), labelText: 'Usuário'),
                  ),
                ),
                Container(
                  margin: EdgeInsets.all(20.0),
                  child: TextFormField(
                    textInputAction: TextInputAction.next,
                    focusNode: _passwordNode,
                    decoration: InputDecoration(
                        border: OutlineInputBorder(), labelText: 'Senha'),
                  ),
                ),
                Container(
                  margin: EdgeInsets.all(20.0),
                  child: MaterialButton(
                    color: Colors.redAccent,
                    textColor: Colors.white,
                    onPressed: () => {},
                    child: Text('Registrar'),
                  ),
                )
              ]),
            ),
          ],
        ),
      ),
    ),
  ),
);

// If you need to scroll entire page

you need to wrap your Form widget inside the SingleChildScrollView widget.

SingleChildScrollView( scrollDirection: Axis.vertical, child: Form() // wrap your entire Form here. )