import 'package:flutter/material.dart'; // `RadioListTile` that can trigger `onChanged` on tap when already selected, if `reselectable` is true class AvesRadioListTile extends StatelessWidget { final T value; final T groupValue; final ValueChanged 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( 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, ), ), ); } }