import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'alert_dialog.dart'; class VSelectModel { VSelectModel({required this.name, required this.code}); final String name; final String code; } class VDialogSelect extends StatelessWidget { /// 数据集 final List source; /// 初始值 final TValue? initialValue; /// 弹窗标题 final String? title; /// 选项文本提取函数 final String Function(T data)? labelGetter; /// 选项外显组件构建器 final Widget Function(T data)? labelBuilder; /// 选项值提取函数 final TValue Function(T data) valueGetter; const VDialogSelect({ super.key, required this.source, this.title, this.initialValue, this.labelGetter, this.labelBuilder, required this.valueGetter, }) : assert(labelGetter != null || labelBuilder != null); Future show() => VAlertDialog.showDialog(this); @override Widget build(BuildContext context) { return VAlertDialog( width: 460, title: title, content: Scrollbar( thumbVisibility: true, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: _buildOptions(context), ), ), ), showCancel: true, ); } List _buildOptions(BuildContext context) { final primaryColor = Theme.of(context).primaryColor; final children = []; for (var i = 0; i < source.length; i++) { final data = source[i]; final val = valueGetter(data); final isSelected = initialValue == val; Widget label; if (labelBuilder != null) { label = labelBuilder!(data); } else { label = Text( labelGetter!(data), style: TextStyle( color: isSelected ? primaryColor : Colors.black, fontSize: 20, ), ); } final widget = Container( alignment: Alignment.centerLeft, height: 56, padding: const EdgeInsets.symmetric(horizontal: 8), color: isSelected ? Theme.of(context).secondaryHeaderColor : null, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( mainAxisSize: MainAxisSize.min, children: [const SizedBox(width: 20), label], ), if (isSelected) Row( children: [ Icon( Icons.check, size: 24, color: primaryColor, ), const SizedBox(width: 20) ], ), ], ), ); children.add( Material( color: Colors.transparent, child: Ink( child: InkWell( onTap: () { _onSelected(val); }, child: widget, ), ), ), ); } return children; } void _onSelected(TValue value) { Get.back(result: value); } }