import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; /// 选择结果(新增) class PickerResult { final T value; final int index; PickerResult(this.value, this.index); } /// 通用底部弹窗选择器 class BottomPicker { /// 显示底部选择器弹窗 /// /// [withIndex] = true 时返回 PickerResult /// [withIndex] = false 时返回 T(兼容旧代码) static Future show( BuildContext context, { required List items, required Widget Function(T item) itemBuilder, int initialIndex = 0, double itemExtent = 50.0, double height = 250, /// 新增参数 bool withIndex = false, }) { if (items.isEmpty) return Future.value(null); final safeIndex = initialIndex.clamp(0, items.length - 1); T selected = items[safeIndex]; int selectedIndex = safeIndex; return showModalBottomSheet( context: context, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(12)), ), builder: (ctx) { return SizedBox( height: height, child: Column( children: [ // 按钮行 Padding( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextButton( onPressed: () { FocusScope.of(context).unfocus(); Navigator.of(ctx).pop(); }, child: const Text( '取消', style: TextStyle(color: Colors.black54, fontSize: 16), ), ), TextButton( onPressed: () { FocusScope.of(context).unfocus(); if (withIndex) { Navigator.of(ctx).pop( PickerResult(selected, selectedIndex), ); } else { Navigator.of(ctx).pop(selected); } }, child: const Text( '确定', style: TextStyle(color: Colors.blue, fontSize: 16), ), ), ], ), ), const Divider(height: 1), // 滚动选择器 Expanded( child: CupertinoPicker( scrollController: FixedExtentScrollController( initialItem: initialIndex, ), itemExtent: itemExtent, onSelectedItemChanged: (index) { selected = items[index]; selectedIndex = index; }, children: items .map((item) => Center(child: itemBuilder(item))) .toList(), ), ), ], ), ); }, ); } }