Respecting the Softkeyboard Insets
There are a problem faced by many flutter developers while working with soft keyboard inputs in the lower portion of the screen. The problem is whenever a user attempts to fill an input form (whose parent widget is a Card, Container, or something similar) in the lower part of the screen, the soft-keyboard tends to cover that form. The same problem will be replicated below and will show a simple solution to this problem.
Problem :
When the user tries to fill the input form the soft keyboard covers the form and the user can’t move to another line without going back from the keyboard.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late TextEditingController _nameEditingController;
late TextEditingController _addressEditingController;
String name = "", address = "";
@override
void initState() {
_nameEditingController = TextEditingController();
_addressEditingController = TextEditingController();
super.initState();
}
@override
void dispose() {
_nameEditingController.dispose();
_addressEditingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Respecting the Softkeyboard Insets')),
body: Center(
child: Text("$name, $address"),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.edit),
onPressed: () {
showModalBottomSheet<dynamic>(
context: context,
builder: (context) {
return Wrap(
children: [
Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
TextField(
controller: _nameEditingController,
decoration:
const InputDecoration(labelText: "Name"),
),
TextField(
controller: _addressEditingController,
decoration:
const InputDecoration(labelText: "Address"),
),
TextButton(
onPressed: () {
setState(() {
name = _nameEditingController.text;
address = _addressEditingController.text;
});
Navigator.of(context).pop();
},
child: const Text("Update"))
],
),
)
],
);
});
},
),
);
}
}
Solution :
The solution that we want to achieve is whenever a user taps on the TextFiled and the keyboard comes out the input form should also move up with a height equivalent to the keyboard’s and the form should be scrollable for easy access. This can be achieved in the following steps:
-
Using EdgeInsets.only in the padding of the Container widget. This will give us control over the individual padding.
-
In the bottom argument of the padding, we will use MediaQuery.of(context).viewInsets.bottom to know the height of the keyboard and add it to the bottom padding. This way we whenever the keyboard will appear the form will move up with the height equivalent to that of the keyboard.
-
At last, we will wrap the entire input form with SingleChildScrollView, to make it scrollable. It will make switching to the next input field easier.
showModalBottomSheet<dynamic>(
context: context,
builder: (context) {
return Wrap(
children: [
SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(context).viewInsets.bottom + 10),
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
TextField(
controller: _nameEditingController,
decoration:
const InputDecoration(labelText: "Name"),
),
TextField(
controller: _addressEditingController,
decoration:
const InputDecoration(labelText: "Address"),
),
TextButton(
onPressed: () {
setState(() {
name = _nameEditingController.text;
address = _addressEditingController.text;
});
Navigator.of(context).pop();
},
child: const Text("Update"))
],
),
),
)
],
);
}
This is how the input form will behave after the correction. The input form moves up in accordance with the height of the soft-keyboard, which makes all the fields visible. And in addition to that, the form is also scrollable now.
Source : geeksforgeeks