in example/lib/pages/settings/settings_page.dart [200:293]
Widget _buildTypedSelectionItem<T>(SelectionItem<T> item) {
return FutureBuilder<List<T>>(
future: item.optionsLoader(),
builder: (context, optionsSnapshot) {
if (optionsSnapshot.connectionState == ConnectionState.waiting) {
return ListTile(
title: Text(item.title),
trailing: const CircularProgressIndicator(),
);
} else if (optionsSnapshot.hasError) {
return ListTile(
title: Text(item.title),
subtitle: Text("Error: ${optionsSnapshot.error}"),
);
} else if (optionsSnapshot.hasData) {
final options = optionsSnapshot.data!;
return FutureBuilder<T?>(
future: item.selectedOptionLoader != null
? item.selectedOptionLoader!(options)
: Future.value(options.isNotEmpty ? options.first : null),
builder: (context, selectedSnapshot) {
// 显示加载中状态
if (selectedSnapshot.connectionState == ConnectionState.waiting) {
return ListTile(
title: Text(item.title),
trailing: const CircularProgressIndicator(strokeWidth: 2),
);
}
// 获取当前选中项
final selectedOption = selectedSnapshot.data;
return ListTile(
title: Text(item.title),
subtitle: selectedOption != null
? Text(item.displayFormatter(selectedOption))
: const Text("未选择"),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () async {
final selected = await showDialog<T>(
context: context,
builder: (context) => SimpleDialog(
title: Text(item.title),
children: [
...options.map<Widget>(
(T option) {
final isSelected = selectedOption != null &&
item.displayFormatter(selectedOption) ==
item.displayFormatter(option);
return ListTile(
title: Text(item.displayFormatter(option)),
// 在当前选中项旁边显示勾选图标
trailing: isSelected
? const Icon(Icons.check, color: Colors.blue)
: null,
onTap: () {
Navigator.pop(context, option);
},
);
},
),
// 添加顶部的清除选项
if (selectedOption != null)
ListTile(
leading: const Icon(
Icons.delete_outline,
color: Colors.red,
),
title: const Text(
"清除选择",
style: TextStyle(color: Colors.red),
),
onTap: () {
Navigator.pop(context);
_showClearConfirmDialog<T>(context, item);
},
),
],
),
);
if (selected != null) {
setState(() {
item.onSelected(selected);
});
}
},
);
},
);
}
return const SizedBox.shrink();
},
);
}