fixed selection dialog to close when selecting already selected value
This commit is contained in:
parent
4cbc17cf8f
commit
a7eaf55ed3
3 changed files with 101 additions and 2 deletions
97
lib/widgets/common/aves_radio_list_tile.dart
Normal file
97
lib/widgets/common/aves_radio_list_tile.dart
Normal file
|
@ -0,0 +1,97 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
// `RadioListTile` that can trigger `onChanged` on tap when already selected, if `reselectable` is true
|
||||
class AvesRadioListTile<T> extends StatelessWidget {
|
||||
final T value;
|
||||
final T groupValue;
|
||||
final ValueChanged<T> onChanged;
|
||||
final bool toggleable;
|
||||
final bool reselectable;
|
||||
final Color activeColor;
|
||||
final Widget title;
|
||||
final Widget subtitle;
|
||||
final Widget secondary;
|
||||
final bool isThreeLine;
|
||||
final bool dense;
|
||||
final bool selected;
|
||||
final ListTileControlAffinity controlAffinity;
|
||||
final bool autofocus;
|
||||
|
||||
bool get checked => value == groupValue;
|
||||
|
||||
const AvesRadioListTile({
|
||||
Key key,
|
||||
@required this.value,
|
||||
@required this.groupValue,
|
||||
@required this.onChanged,
|
||||
this.toggleable = false,
|
||||
this.reselectable = false,
|
||||
this.activeColor,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.isThreeLine = false,
|
||||
this.dense,
|
||||
this.secondary,
|
||||
this.selected = false,
|
||||
this.controlAffinity = ListTileControlAffinity.platform,
|
||||
this.autofocus = false,
|
||||
}) : assert(toggleable != null),
|
||||
assert(isThreeLine != null),
|
||||
assert(!isThreeLine || subtitle != null),
|
||||
assert(selected != null),
|
||||
assert(controlAffinity != null),
|
||||
assert(autofocus != null),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Widget control = Radio<T>(
|
||||
value: value,
|
||||
groupValue: groupValue,
|
||||
onChanged: onChanged,
|
||||
toggleable: toggleable,
|
||||
activeColor: activeColor,
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
autofocus: autofocus,
|
||||
);
|
||||
Widget leading, trailing;
|
||||
switch (controlAffinity) {
|
||||
case ListTileControlAffinity.leading:
|
||||
case ListTileControlAffinity.platform:
|
||||
leading = control;
|
||||
trailing = secondary;
|
||||
break;
|
||||
case ListTileControlAffinity.trailing:
|
||||
leading = secondary;
|
||||
trailing = control;
|
||||
break;
|
||||
}
|
||||
return MergeSemantics(
|
||||
child: ListTileTheme.merge(
|
||||
selectedColor: activeColor ?? Theme.of(context).accentColor,
|
||||
child: ListTile(
|
||||
leading: leading,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
trailing: trailing,
|
||||
isThreeLine: isThreeLine,
|
||||
dense: dense,
|
||||
enabled: onChanged != null,
|
||||
onTap: onChanged != null
|
||||
? () {
|
||||
if (toggleable && checked) {
|
||||
onChanged(null);
|
||||
return;
|
||||
}
|
||||
if (reselectable || !checked) {
|
||||
onChanged(value);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
selected: selected,
|
||||
autofocus: autofocus,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:aves/widgets/common/aves_radio_list_tile.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
|
@ -46,7 +47,7 @@ class _AvesSelectionDialogState<T> extends State<AvesSelectionDialog> {
|
|||
}
|
||||
|
||||
Widget _buildRadioListTile(T value, String title) {
|
||||
return RadioListTile<T>(
|
||||
return AvesRadioListTile<T>(
|
||||
key: Key(value.toString()),
|
||||
value: value,
|
||||
groupValue: _selectedValue,
|
||||
|
@ -55,6 +56,7 @@ class _AvesSelectionDialogState<T> extends State<AvesSelectionDialog> {
|
|||
Navigator.pop(context, _selectedValue);
|
||||
setState(() {});
|
||||
},
|
||||
reselectable: true,
|
||||
title: Text(
|
||||
title,
|
||||
softWrap: false,
|
||||
|
|
|
@ -102,7 +102,7 @@ class _WelcomePageState extends State<WelcomePage> {
|
|||
text: 'Allow anonymous crash reporting',
|
||||
),
|
||||
LabeledCheckbox(
|
||||
key: Key('agree-termsCheckbox'),
|
||||
key: Key('agree-checkbox'),
|
||||
value: _hasAcceptedTerms,
|
||||
onChanged: (v) => setState(() => _hasAcceptedTerms = v),
|
||||
text: 'I agree to the terms and conditions',
|
||||
|
|
Loading…
Reference in a new issue