flutterflutter-dialog

Flutter AlertDialog with Strange Scrolling Behavior


I'm encountering a strange issue with AlertDialog in Flutter, specifically with its scrolling behavior. The AlertDialog displays as intended and its basic functionalities work properly. However, when the content exceeds the screen size, due to the added pictures, the dialog's scroll behavior becomes weird.

Here's a simplified version of my code:

void openDialog() {
  showDialog(
    context: context, 
    builder: (context) {
      return SingleChildScrollView(
        child: StatefulBuilder(
          builder: (context, setState) => AlertDialog(
            content: SingleChildScrollView(
              child: Form(
                key: _formKey,
                child: Column(
                  children: <Widget>[
                    // TextFormFields for input
                    TextFormField(decoration: const InputDecoration(labelText: "Field1")),
                    // Additional TextFormField and ElevatedButton for adding images
                    // Visibility widget containing a ListView.builder for the selected images
                    Visibility(
                      visible: selectedImages.isNotEmpty,
                      child: ListView.builder(
                        shrinkWrap: true,
                        itemCount: selectedImages.length,
                        itemBuilder: (context, index) {
                          // Image display and TextFormField for image label
                        },
                      ),
                    ),
                    ElevatedButton(
                      onPressed: () => Navigator.pop(context),
                      child: const Text("Close"),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      );
    }
  );
}

The dialog becomes scrollable when pictures are added. However, I can only scroll the dialog by interacting with the upper part (e.g., the TextFormFields). Attempting to scroll by touching the lower part, where the pictures are displayed, results in what appears to be an attempt to scroll the ListView of pictures, instead of the entire dialog.

I've already tried rearranging the widgets, such as wrapping the content in a SingleChildScrollView, but the issue remains.

Does anyone know how to fix this behavior, so the entire dialog scrolls uniformly, regardless of where I initiate the scroll?

Thank you!


Solution

  • I have created a minimally reproducible example of an AlertDialog that is scrollable as expected. I have removed the StatefulBuilder which has caused the problem as well as the second SingleChildScrollView (pointed out by Rahul).

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MaterialApp(home: MainApp(),));
    }
    
    class MainApp extends StatelessWidget {
      const MainApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: TextButton(onPressed:() {
              showDialog(
                context: context, 
                builder: (context) {
                  return SingleChildScrollView(
                    child: AlertDialog(
                      content: Form(
                        child: Column(
                          children: <Widget>[
                            Image.asset('assets/images/1.png'),
                            TextFormField(decoration: const InputDecoration(labelText: "Field1")),
                            Image.asset('assets/images/2.png'),
                            TextFormField(decoration: const InputDecoration(labelText: "Field2")),
                            Image.asset('assets/images/3.png'),
                            TextFormField(decoration: const InputDecoration(labelText: "Field3")),
                            ElevatedButton(
                              onPressed: () => Navigator.pop(context),
                              child: const Text("Close"),
                            ),
                          ],
                        ),
                      ),
                    )
                  );
                },
              );
            }, child: const Text('Dialog'),),
          ),
        );
      }
    }