FormeListTile<T extends Object> constructor
FormeListTile<T extends Object> ({
- Key? key,
- String? name,
- List<
T> initialValue = const [], - FormeAsyncValidator<
List< ? asyncValidator,T> > - Duration? asyncValidatorDebounce,
- AutovalidateMode? autovalidateMode,
- bool enabled = true,
- FocusNode? focusNode,
- FormeFieldInitialized<
List< ? onInitialized,T> > - FormeFieldSetter<
List< ? onSaved,T> > - FormeFieldStatusChanged<
List< ? onStatusChanged,T> > - int? order,
- bool quietlyValidate = false,
- bool readOnly = false,
- bool requestFocusOnUserInteraction = true,
- FormeFieldValidationFilter<
List< ? validationFilter,T> > - FormeValidator<
List< ? validator,T> > - FormeFieldDecorator<
List< ? decorator,T> > - int? maxSelectedCount,
- WrapAlignment alignment = WrapAlignment.start,
- Clip? clipBehavior,
- EdgeInsetsGeometry? contentPadding,
- WrapCrossAlignment crossAxisAlignment = WrapCrossAlignment.start,
- InputDecoration? decoration,
- bool dense = true,
- Axis direction = Axis.horizontal,
- bool? enableFeedback,
- double? horizontalTitleGap,
- Color? iconColor,
- VoidCallback? maxSelectedExceedCallback,
- double? minLeadingWidth,
- double? minVerticalPadding,
- WrapAlignment runAlignment = WrapAlignment.start,
- double runSpacing = 0.0,
- Color? selectedColor,
- Color? selectedTileColor,
- ShapeBorder? shape,
- double spacing = 0.0,
- int split = 2,
- ListTileStyle? style,
- Color? textColor,
- TextDirection? textDirection,
- Color? tileColor,
- FormeListTileType type = FormeListTileType.checkbox,
- VerticalDirection verticalDirection = VerticalDirection.down,
- required List<
FormeListTileItem< items,T> >
Implementation
FormeListTile({
super.key,
super.name,
super.initialValue = const [],
super.asyncValidator,
super.asyncValidatorDebounce,
super.autovalidateMode,
super.enabled = true,
super.focusNode,
super.onInitialized,
super.onSaved,
super.onStatusChanged,
super.order,
super.quietlyValidate = false,
super.readOnly = false,
super.requestFocusOnUserInteraction = true,
super.validationFilter,
super.validator,
FormeFieldDecorator<List<T>>? decorator,
this.maxSelectedCount,
this.alignment = WrapAlignment.start,
this.clipBehavior,
this.contentPadding,
this.crossAxisAlignment = WrapCrossAlignment.start,
this.decoration,
this.dense = true,
this.direction = Axis.horizontal,
this.enableFeedback,
this.horizontalTitleGap,
this.iconColor,
this.maxSelectedExceedCallback,
this.minLeadingWidth,
this.minVerticalPadding,
this.runAlignment = WrapAlignment.start,
this.runSpacing = 0.0,
this.selectedColor,
this.selectedTileColor,
this.shape,
this.spacing = 0.0,
this.split = 2,
this.style,
this.textColor,
this.textDirection,
this.tileColor,
this.type = FormeListTileType.checkbox,
this.verticalDirection = VerticalDirection.down,
required this.items,
}) : super.allFields(
decorator: decorator ??
(decoration == null
? null
: FormeInputDecorationDecorator(
maxLength: maxSelectedCount,
decorationBuilder: (context) => decoration)),
builder: (state) {
final bool readOnly = state.readOnly;
final List<Widget> wrapWidgets = [];
void changeValue(T value) {
final List<T> values = List.of(state.value);
if (!values.remove(value)) {
if (maxSelectedCount != null &&
values.length >= maxSelectedCount) {
if (maxSelectedExceedCallback != null) {
maxSelectedExceedCallback();
}
return;
}
values.add(value);
}
state.didChange(values);
state.requestFocusOnUserInteraction();
}
Widget createFormeListTileItem(
FormeListTileItem<T> item, bool selected, bool readOnly) {
switch (type) {
case FormeListTileType.checkbox:
return CheckboxListTile(
enableFeedback: item.enableFeedback,
visualDensity: item.visualDensity,
side: item.side,
tristate: false,
isThreeLine: item.isThreeLine ?? false,
shape: item.shape,
tileColor: item.tileColor,
selectedTileColor: item.selectedTileColor,
activeColor: item.activeColor,
checkColor: item.checkColor,
secondary: item.secondary,
subtitle: item.subtitle,
controlAffinity: item.controlAffinity,
contentPadding: item.padding,
dense: item.dense,
title: item.title,
checkboxShape: item.checkboxShape,
value: selected,
onChanged:
readOnly ? null : (v) => changeValue(item.data),
);
case FormeListTileType.switchs:
return SwitchListTile(
enableFeedback: item.enableFeedback,
visualDensity: item.visualDensity,
isThreeLine: item.isThreeLine ?? false,
tileColor: item.tileColor,
activeColor: item.activeColor,
shape: item.shape,
selectedTileColor: item.selectedTileColor,
secondary: item.secondary,
subtitle: item.subtitle,
controlAffinity: item.controlAffinity,
contentPadding: item.padding,
dense: item.dense,
title: item.title,
hoverColor: item.hoverColor,
activeTrackColor: item.activeTrackColor,
inactiveThumbColor: item.inactiveThumbColor,
inactiveTrackColor: item.inactiveTrackColor,
activeThumbImage: item.activeThumbImage,
inactiveThumbImage: item.inactiveThumbImage,
value: selected,
onChanged:
readOnly ? null : (v) => changeValue(item.data),
);
}
}
Widget createCommonItem(
FormeListTileItem<T> item, bool selected, bool readOnly) {
switch (type) {
case FormeListTileType.checkbox:
return Checkbox(
tristate: false,
side: item.side,
activeColor: item.activeColor,
checkColor: item.checkColor,
mouseCursor: item.mouseCursor,
shape: item.checkboxShape,
fillColor: item.fillColor,
materialTapTargetSize: item.materialTapTargetSize,
focusColor: item.focusColor,
hoverColor: item.hoverColor,
overlayColor: item.overlayColor,
splashRadius: item.splashRadius,
visualDensity: item.visualDensity,
value: selected,
onChanged: readOnly || item.readOnly
? null
: (v) => changeValue(item.data),
);
case FormeListTileType.switchs:
return Switch(
value: selected,
onChanged: readOnly || item.readOnly
? null
: (v) => changeValue(item.data),
activeColor: item.activeColor,
activeTrackColor: item.activeTrackColor,
inactiveThumbColor: item.inactiveThumbColor,
inactiveTrackColor: item.inactiveTrackColor,
activeThumbImage: item.activeThumbImage,
inactiveThumbImage: item.inactiveThumbImage,
materialTapTargetSize: item.materialTapTargetSize,
focusColor: item.focusColor,
hoverColor: item.hoverColor,
overlayColor: item.overlayColor,
splashRadius: item.splashRadius,
thumbColor: item.thumbColor,
trackColor: item.trackColor,
dragStartBehavior:
item.dragStartBehavior ?? DragStartBehavior.start,
onActiveThumbImageError: item.onActiveThumbImageError,
onInactiveThumbImageError: item.onInactiveThumbImageError,
thumbIcon: item.thumbIcon,
mouseCursor: item.mouseCursor,
);
}
}
for (int i = 0; i < items.length; i++) {
final FormeListTileItem<T> item = items[i];
final bool isReadOnly = readOnly || item.readOnly;
final bool selected = state.value.contains(item.data);
if (split > 0) {
final double factor = 1 / split;
if (factor == 1) {
wrapWidgets.add(
createFormeListTileItem(item, selected, isReadOnly));
continue;
}
}
final Widget tileItem =
createCommonItem(item, selected, readOnly);
final Widget title = split == 0
? item.title
: Flexible(
child: item.title,
);
List<Widget> children;
switch (item.controlAffinity) {
case ListTileControlAffinity.leading:
children = [tileItem, title];
break;
default:
children = [title, tileItem];
break;
}
final Row tileItemRow = Row(
mainAxisSize: MainAxisSize.min,
children: children,
);
final Widget groupItemWidget = Padding(
padding: item.padding,
child: InkWell(
borderRadius:
const BorderRadius.all(Radius.circular(4.0)),
onTap: isReadOnly
? null
: () {
changeValue(item.data);
},
child: tileItemRow),
);
final bool visible = item.visible;
if (split <= 0) {
wrapWidgets.add(Visibility(
visible: visible,
child: groupItemWidget,
));
if (visible && i < items.length - 1) {
wrapWidgets.add(const SizedBox(
width: 8.0,
));
}
} else {
final double factor = item.ignoreSplit ? 1 : 1 / split;
wrapWidgets.add(Visibility(
visible: visible,
child: FractionallySizedBox(
widthFactor: factor,
child: groupItemWidget,
),
));
}
}
Widget child = Wrap(
spacing: spacing,
runSpacing: runSpacing,
textDirection: textDirection,
crossAxisAlignment: crossAxisAlignment,
verticalDirection: verticalDirection,
alignment: alignment,
direction: direction,
runAlignment: runAlignment,
clipBehavior: clipBehavior ?? Clip.none,
children: wrapWidgets,
);
if (split == 1) {
child = ListTileTheme.merge(
child: child,
dense: dense,
shape: shape,
style: style,
selectedColor: selectedColor,
iconColor: iconColor,
textColor: textColor,
contentPadding: contentPadding,
tileColor: tileColor,
selectedTileColor: selectedTileColor,
enableFeedback: enableFeedback,
horizontalTitleGap: horizontalTitleGap,
minVerticalPadding: minVerticalPadding,
minLeadingWidth: minLeadingWidth,
);
}
return Focus(
focusNode: state.focusNode,
child: child,
);
});