Reputation: 2117
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:
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 ?
Upvotes: 1
Views: 88
Reputation: 183
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: -
Upvotes: 2
Reputation: 17140
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"),
Upvotes: 0