97 lines
2.7 KiB
Dart
97 lines
2.7 KiB
Dart
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,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|