1

I have a simple ListView in my alert dialog. It allows a user to make selection and once selected, the list tile color changes.

The weird issue that I am having is for the selected tiles, when I scroll, it overlaps with the title of the dialog:

enter image description here enter image description here

But for the other unselected tiles, it just goes under the title as desired.

My code is as below:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mauritius_emergency_services/core/models/service.dart';
import 'package:mauritius_emergency_services/core/providers/services.dart';
import 'package:mauritius_emergency_services/core/providers/settings.dart';

class EmergencyButtonDialog extends ConsumerWidget {
  const EmergencyButtonDialog({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final settings = ref.watch(settingsProvider);
    final uiState = ref.watch(servicesProvider).when(
          data: (services) => ServiceListView(
            services: services,
            selectedService: settings.emergencyButtonAction,
            onServiceSelected: (service) {
              ref
                  .read(settingsProvider.notifier)
                  .updateEmergencyButtonAction(service);
            },
          ),
          loading: () => const CircularProgressIndicator(),
          error: (error, stack) => const Text("Error occurred"),
        );

    return AlertDialog(
      title: const Text("Choose Emergency Action"),
      contentPadding: EdgeInsets.zero, // Remove default padding
      content: SizedBox(
        width: double.maxFinite,
        height: 300,
        child: uiState,
      ),
    );
  }
}

class ServiceListView extends StatelessWidget {
  final List<Service> services;
  final Service selectedService;
  final Function(Service) onServiceSelected;

  const ServiceListView({
    super.key,
    required this.services,
    required this.selectedService,
    required this.onServiceSelected,
  });

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: services
          .map(
            (service) => ListTile(
              selected: service.identifier == selectedService.identifier,
              selectedColor: Theme.of(context).colorScheme.onTertiary,
              selectedTileColor: Theme.of(context).colorScheme.tertiary,
              title: Text(service.name),
              subtitle: Text(service.mainContact.toString()),
              trailing: service.identifier == selectedService.identifier
                  ? Icon(
                      Icons.check_circle,
                      color: Theme.of(context).colorScheme.onTertiary,
                    )
                  : null,
              onTap: () {
                onServiceSelected(service);
              },
            ),
          )
          .toList(),
    );
  }
}

And this is how i launch my dialog:

showDialog<String>(
              context: context,
              builder: (BuildContext context) => LanguageDialog(),
            );

Anyone know why this is happening ?

1
  • Good stuff! I marked it as working. Thanks a lot man. I have others issues in flutter. IF you could help me in those as well. Check my stack questions Commented Jan 13 at 16:40

2 Answers 2

2
+50

Solution for this is to remove the title padding of AlertDialog then surrounding the Text Widget of title property of AlertDialog by Container Widget , then giving Container the same color and height as that of AlertDialog title and finally changing clipBehavior propery of AlertDialog to Clip.hardEdge.

Full Code : -

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Box(),
    );
  }
}

class Box extends StatefulWidget {
  const Box({super.key});

  @override
  State<Box> createState() => _BoxState();
}

class _BoxState extends State<Box> {
  var selectedIndex = List<List>.generate(
      10, (i) => List<dynamic>.generate(10, (index) => false, growable: false),
      growable: false);

  Widget dialog() {
    return Center(
        child: ListView(children: [
      for (int i = 0; i < 5; i++) ...[
        StatefulBuilder(builder: (context, StateSetter setState) {
          return AlertDialog(
            clipBehavior: Clip.hardEdge,
            contentPadding: EdgeInsets.zero,
            titlePadding: EdgeInsets.zero,
            title: Container(
              width: double.infinity,
              height: 75,
              decoration: BoxDecoration(
                  color: Theme.of(context).colorScheme.surfaceContainerHigh,
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(25),
                    topRight: Radius.circular(25),
                  )),
              alignment: Alignment.center,
              child: Text("Choose Emergency Action"),
            ),
            content: SizedBox(
              width: double.maxFinite,
              height: 300,
              child: SingleChildScrollView(
                child: Column(
                  children: [
                    for (int j = 0; j < 10; j++) ...[
                      ListTile(
                        selected: selectedIndex[i][j],
                        title: Text(
                          'Item : - $j',
                        ),
                        contentPadding: EdgeInsets.all(10),
                        selectedTileColor: Colors.purple[400],
                        onTap: () {
                          setState(() {
                            selectedIndex[i][j] = !selectedIndex[i][j];
                          });
                        },
                      ),
                    ]
                  ],
                ),
              ),
            ),
          );
        })
      ]
    ]));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: GestureDetector(
          onTap: () {
            showDialog<String>(
              context: context,
              builder: (BuildContext context) => dialog(),
            );
          },
          child: Text('open dialog')),
    ));
  }
}

Output: -

Sign up to request clarification or add additional context in comments.

Comments

0

Your title text is too large.

You can reduce the text size:

title: const Text("Choose Emergency Action",
                    style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.normal)),

Or the text length:

title: const Text("Choose Action"),

1 Comment

Still goes through...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.