In my Flutter application, I'm facing a challenge with making my screen scrollable to deal with dynamically added content. Initially, I have a Form
displayed on the screen with several TextFormField
widgets. Users can add pictures from their phone, which are then displayed on the screen along with additional TextFormField
widgets for labeling the images. Despite using SingleChildScrollView
, I can't seem to achieve the desired scrollable effect for the entire screen after adding the pictures.
Below is the code snippet I'm working with:
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
// TextFormFields for input
Visibility(
visible: ref.watch(selectedImagesProvider).isNotEmpty,
child: ListView.builder(
itemCount: selectedImages.length,
itemBuilder: (context, index) {
// Display added images with TextFormField for each
},
),
),
// Button for adding/changing images
],
),
),
),
),
// Upload button
],
),
),
);
My goal is for the entire page to be scrollable once images are added, not just the images section. Currently, if many pictures are added, they extend beyond the screen size, but I cannot scroll through all the content seamlessly.
I tried following Diego's suggestion but couldn't get the result I wanted. Is there an alternative approach to ListView.builder
that would allow the images and the form to be part of a single, scrollable page? I want to avoid having the images section be independently scrollable from the rest of the form.
Any advice on how to adjust my layout or components to achieve a fully scrollable page that dynamically adjusts to content would be greatly appreciated.
Thank you for your help!
You don't need to add extra complex Widget for this, all what you need are:
I added a button at the bottom and it's fixed, so you will always see the button and don't need to scroll.
Result:
Code:
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// Replace `Widget` by `File` if you want.
List<Widget> list = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Form(
child: Column(
children: <Widget>[
...List.generate(
5,
(index) => const Padding(
padding: EdgeInsets.all(15.0),
child: TextField(),
),
),
if (list.isNotEmpty) ...[
...List.generate(
list.length,
(index) => Padding(
padding: const EdgeInsets.all(15.0),
child: list[index],
),
),
],
],
),
),
),
),
// BUTTON
ElevatedButton(
onPressed: () {
// you can replace the placeholder to any File
setState(() {
list.add(const Placeholder(
fallbackHeight: 100,
fallbackWidth: 100,
));
});
},
child: const Text('Add Item'),
),
],
),
),
);
}
}