Discover the top AI trends for startups in...
If the Flutter keyboard is covering your TextField,
the problem is usually related to the screen's layout not resizing or
scrolling when the keyboard appears.
Common solutions include using Scaffold correctly, enabling
keyboard resizing, wrapping your content with
SingleChildScrollView, using ListView, or
applying appropriate bottom padding based on
MediaQuery.viewInsets.
The correct solution depends on how your screen is structured.
Why Does the Keyboard Cover a TextField in Flutter?
When the user taps a TextField, Flutter displays the
on-screen keyboard. The keyboard occupies part of the screen, reducing
the available vertical space.
If your widget tree does not respond to this reduced space, the keyboard can appear on top of the input field.
For example:
Before Keyboard
┌─────────────────────┐
│ │
│ TextField │
│ │
│ Button │
│ │
└─────────────────────┘
After Keyboard
┌─────────────────────┐
│ │
│ TextField │
│ │
├─────────────────────┤
│ KEYBOARD │
│ │
└─────────────────────┘
The TextField has not necessarily moved. Instead, the
available screen area has become smaller.
Quick Fix: Use SingleChildScrollView
For a simple form, one of the easiest solutions is to make the content scrollable.
Scaffold(
appBar: AppBar(
title: const Text('Login'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
TextField(
decoration: const InputDecoration(
labelText: 'Email',
),
),
const SizedBox(height: 16),
TextField(
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {},
child: const Text('Login'),
),
],
),
),
);
When the keyboard reduces the available screen height, the user can
scroll to the TextField. For many simple forms, this is
enough.
1. Check Scaffold's resizeToAvoidBottomInset
Flutter's Scaffold has a property called
resizeToAvoidBottomInset. It determines whether the body
should resize to avoid system UI such as the keyboard.
Normally, you can leave it enabled:
Scaffold(
resizeToAvoidBottomInset: true,
body: YourWidget(),
);
true is the default behavior. If you have explicitly set:
resizeToAvoidBottomInset: false,
the body may not resize when the keyboard opens.
Try changing it to:
resizeToAvoidBottomInset: true,
or remove the property and allow the default behavior.
2. Use MediaQuery.viewInsets for Custom Layouts
For more customized layouts, you can detect how much space the keyboard occupies.
Flutter exposes this through:
MediaQuery.of(context).viewInsets.bottom
When the keyboard is open, viewInsets.bottom represents the
area covered by the keyboard. You can use it as bottom padding:
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: YourWidget(),
)
This is useful when you have a custom layout that needs to react directly to keyboard height.
3. Use AnimatedPadding for a Smoother UI
If you want the layout to move smoothly when the keyboard opens,
AnimatedPadding can be useful.
AnimatedPadding(
duration: const Duration(milliseconds: 200),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: YourWidget(),
)
The padding changes when the keyboard appears, creating a smoother transition.
4. Use ListView for Long Forms
If your screen contains multiple fields, a ListView is often
more appropriate than a Column.
Scaffold(
body: ListView(
padding: const EdgeInsets.all(16),
children: [
TextField(
decoration: const InputDecoration(
labelText: 'Name',
),
),
const SizedBox(height: 16),
TextField(
decoration: const InputDecoration(
labelText: 'Email',
),
),
const SizedBox(height: 16),
TextField(
decoration: const InputDecoration(
labelText: 'Phone',
),
),
const SizedBox(height: 16),
TextField(
decoration: const InputDecoration(
labelText: 'Message',
),
),
],
),
);
A scrollable layout allows the user to move the focused field above the keyboard. For registration, checkout, address and feedback forms, this pattern is often more practical.
5. What If SingleChildScrollView Still Doesn't Work?
Sometimes, SingleChildScrollView is not the real problem.
The keyboard may be blocked by the way your widgets are arranged.
For example, if you have a fixed widget at the bottom:
Column(
children: [
Expanded(
child: YourContent(),
),
YourBottomWidget(),
],
)
When the keyboard opens, the available screen space becomes smaller. The
bottom widget can take up some of that space, making it difficult for the
TextField to stay visible.
A simple solution is to make the entire form scrollable:
Scaffold(
body: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// Your form fields
],
),
),
),
);
Now, when the keyboard appears, the user can
scroll the form to reach the TextField
instead of having it hidden behind the keyboard.
The important point is: make the content containing your
TextField scrollable, especially when your screen
has multiple widgets or a fixed bottom section.
6. SafeArea Does Not Automatically Solve Keyboard Problems
SafeArea protects content from areas such as system status
bars and navigation areas.
SafeArea(
child: YourWidget(),
)
However, SafeArea should not be treated as the complete
solution for a keyboard-covered TextField. The keyboard
problem usually requires a resizable or scrollable layout.
A common combination is:
Scaffold(
resizeToAvoidBottomInset: true,
body: SafeArea(
child: SingleChildScrollView(
child: YourForm(),
),
),
);
7. Avoid Hard-Coded Screen Heights
A common cause of keyboard-overlap problems is a fixed height.
For example:
Container(
height: 700,
child: YourForm(),
)
This can become problematic when the keyboard reduces the available screen height.
Prefer flexible layouts:
Expanded(
child: YourWidget(),
)
or scrollable layouts:
SingleChildScrollView(
child: YourWidget(),
)
Responsive layouts are generally better for different screen sizes and keyboard configurations.
8. What About Text Fields Inside a Dialog?
Keyboard handling can be slightly different when the
TextField is inside a dialog or bottom sheet.
For example, a form inside a modal bottom sheet may need to account for the keyboard explicitly:
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: YourForm(),
);
},
);
The combination of isScrollControlled: true and
keyboard-aware padding is commonly useful for forms displayed inside
modal bottom sheets.
9. TextField Inside a Column: A Common Problem
Consider this layout:
Column(
children: [
const Spacer(),
TextField(),
const Spacer(),
],
)
When the keyboard opens, the available vertical space changes significantly.
Instead of depending heavily on Spacer() and fixed
positioning, consider making the content scrollable:
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
TextField(),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {},
child: const Text('Submit'),
),
],
),
)
This allows the user to reach the input field even when the keyboard occupies a large portion of the screen.
10. Use FocusNode When You Need More Control
For complex forms, you may want to control which field receives focus.
final emailFocusNode = FocusNode();
TextField(
focusNode: emailFocusNode,
decoration: const InputDecoration(
labelText: 'Email',
),
);
You can move focus between fields:
FocusScope.of(context).nextFocus();
This can improve form navigation, especially when users move between multiple fields using the keyboard's Next button.
Recommended Layout for a Flutter Form
For a standard form, this is a good starting structure:
Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: const Text('Registration'),
),
body: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
decoration: const InputDecoration(
labelText: 'Name',
),
),
const SizedBox(height: 16),
TextField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email',
),
),
const SizedBox(height: 16),
TextField(
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: 'Phone',
),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {},
child: const Text('Submit'),
),
],
),
),
),
);
This structure handles many common keyboard-overlap situations without requiring complicated keyboard calculations.
Common Flutter Keyboard Problems and Solutions
| Problem | Possible Solution |
|---|---|
Keyboard covers TextField |
Use SingleChildScrollView |
| Screen doesn't resize | Check resizeToAvoidBottomInset |
| Long form | Use ListView |
| Custom keyboard spacing | Use MediaQuery.viewInsets.bottom |
| Smooth keyboard movement | Use AnimatedPadding |
| Bottom sheet field is covered | Use isScrollControlled: true |
| Fixed-height layout | Replace with flexible or scrollable layout |
| Complex field navigation | Use FocusNode and FocusScope |
| Content hidden behind system areas | Use SafeArea |
Why Does Flutter Not Automatically Scroll Every TextField?
Flutter's layout system does not mean that every arbitrary widget hierarchy
will automatically scroll the focused TextField into the
ideal visible position.
Whether the field remains visible depends on the structure of the surrounding widgets and how the screen responds to the keyboard's reduced viewport.
This is why scrollable form layouts are usually preferable to manually positioning every field.
Best Practice: Make Forms Keyboard-Aware
For Short Forms
Use:
Scaffold
└── SingleChildScrollView
└── Column
└── TextFields
For Long Forms
Use:
Scaffold
└── ListView
└── TextFields
For Custom Layouts
Use:
Scaffold
└── Keyboard-aware padding
└── Custom content
And access:
MediaQuery.of(context).viewInsets.bottom
For Bottom Sheets
Consider:
isScrollControlled: true
and keyboard-aware bottom padding.
Quick Troubleshooting Checklist
If your Flutter keyboard is covering a TextField, check these
items in order:
-
Is your content scrollable?
Try:
SingleChildScrollView(...) -
Did you disable keyboard resizing?
Check:
resizeToAvoidBottomInset -
Are you using fixed heights?
Remove unnecessary values such as:
height: 700 -
Is the form inside a bottom sheet?
Try:
isScrollControlled: true -
Do you need custom keyboard spacing?
Use:
MediaQuery.of(context).viewInsets.bottom -
Is your form inside a complex Column or Stack?
Consider replacing fixed positioning with a scrollable layout.
Frequently Asked Questions
Why is my Flutter keyboard covering my TextField?
The keyboard reduces the available screen space. If the surrounding
layout does not resize or scroll, the keyboard can cover the focused
TextField.
How do I stop the keyboard from covering TextField in Flutter?
For many forms, wrap the content in
SingleChildScrollView and ensure
Scaffold.resizeToAvoidBottomInset is enabled.
What is resizeToAvoidBottomInset in Flutter?
resizeToAvoidBottomInset controls whether the
Scaffold body should resize when system UI such as the
keyboard appears.
How do I add keyboard padding in Flutter?
You can use
MediaQuery.of(context).viewInsets.bottom
to determine the bottom area occupied by the keyboard and use that
value as padding.
Should I use ListView or SingleChildScrollView for a Flutter form?
SingleChildScrollView works well for smaller forms.
ListView is often more appropriate for longer forms
because scrolling is built into the layout.
Why does my TextField work on one phone but not another?
Different devices have different screen sizes, keyboard heights, orientations and system UI configurations. A layout that depends on fixed dimensions may therefore behave differently across devices.
How do I prevent a TextField from being hidden inside a Flutter bottom sheet?
For a bottom-sheet form, consider using
isScrollControlled: true and adding bottom padding based
on MediaQuery.viewInsets.bottom.
Final Answer
If your Flutter keyboard is covering a TextField, start by
making the form scrollable and allowing the Scaffold to
resize around the keyboard.
For a typical form, start with:
Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: YourForm(),
),
);
If that does not solve the issue, inspect fixed heights,
Column/Stack layouts, bottom sheets and custom
positioning. For advanced layouts, use
MediaQuery.viewInsets.bottom to respond directly to the
keyboard.
The best solution depends on the widget hierarchy rather than the
TextField itself.
Technical Disclaimer
Flutter's APIs and recommended patterns can change between framework releases. Always verify implementation details against the Flutter documentation and the version of Flutter used by your project.