I have been searching for so long to find a good solution to my problem. I want to have this layout:
So far I have managed to do this:
class FormPage extends StatefulWidget {
const FormPage({super.key});
@override
State<FormPage> createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
bool hasManyData = false;
// List of many data
final List<String> dataLong = List.generate(20, (index) => "Data $index");
// List of few data
final List<String> dataShort = List.generate(2, (index) => "Data $index");
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
ElevatedButton(
onPressed: () {
setState(() {
hasManyData = !hasManyData;
});
},
child: const Text("change Data Size"),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
for (final data in hasManyData ? dataLong : dataShort)
ListTile(
title: Text(data),
),
const TextField(
decoration: InputDecoration(
hintText: "Name",
),
),
ElevatedButton(
onPressed: () {},
child: const Text("Submit"),
),
],
),
),
),
],
),
),
);
}
}
Which is almost the same but the submit button is not on the bottom when there are few data (you can change data size using the button).
Every way that I have tried so many things with Slivers and without always there was something breaking, I want to keep the keyboard functionality as is without overflowing or the Submit button moving up with the keyboard.
EDIT:
I have managed to do that:
class FormPage extends StatefulWidget {
const FormPage({super.key});
@override
State<FormPage> createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
bool hasManyData = false;
// List of many data
final List<String> dataLong = List.generate(20, (index) => "Data $index");
// List of few data
final List<String> dataShort = List.generate(2, (index) => "Data $index");
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
ElevatedButton(
onPressed: () {
setState(() {
hasManyData = !hasManyData;
});
},
child: const Text("change Data Size"),
),
Expanded(
child: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (final data in hasManyData ? dataLong : dataShort)
ListTile(
title: Text(data),
),
const TextField(
decoration: InputDecoration(
hintText: "Name",
),
),
const Spacer(),
ElevatedButton(
onPressed: () {},
child: const Text("Submit"),
),
],
),
),
],
),
),
],
),
),
);
}
}
But now the submit button gets pushed up when the keyboard opens, and hiding the button when the keyboard opens is an option… but a very bad one imo because it takes a second for it to reapear.
3
Answers
You need to provide padding based on Keyboard’s height. and the the
ElevatedButton
will be outside theExpanded
.First thing take out
ElevatedButton
fromExpanded
widget:Another way to do this, use
Align
widget:Try below code