114 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Dart
		
	
	
| import 'package:flutter/material.dart';
 | |
| import 'package:flutter/cupertino.dart';
 | |
| 
 | |
| /// 通用底部弹窗选择器
 | |
| /// Example:
 | |
| /// ```dart
 | |
| /// final choice = await BottomPickerTwo.show<String>(
 | |
| ///   context,
 | |
| ///   items: ['选项1', '选项2', '选项3'],
 | |
| ///   itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
 | |
| ///   initialIndex: 1,
 | |
| /// );
 | |
| /// if (choice != null) {
 | |
| ///   // 用户点击确定并选择了 choice
 | |
| /// }
 | |
| /// ```
 | |
| class BottomPickerTwo {
 | |
|   /// 显示底部选择器弹窗
 | |
|   ///
 | |
|   /// [items]: 选项列表
 | |
|   /// [itemBuilder]: 每个选项的展示 Widget
 | |
|   /// [initialIndex]: 初始选中索引
 | |
|   /// [itemExtent]: 列表行高
 | |
|   /// [height]: 弹窗总高度
 | |
|   static Future<dynamic> show<T>(
 | |
|     BuildContext context, {
 | |
|     required List<dynamic> items,
 | |
|     required Widget Function(dynamic item) itemBuilder,
 | |
|     int initialIndex = 0,
 | |
|     double itemExtent = 50.0,
 | |
|     double height = 250,
 | |
|     double desiredSpacing = 16.0,
 | |
|   }) {
 | |
|     // 当前选中项
 | |
|     dynamic selected = items[initialIndex];
 | |
| 
 | |
|     return showModalBottomSheet<T>(
 | |
|       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: () => Navigator.of(ctx).pop(),
 | |
|                       child: const Text('取消'),
 | |
|                     ),
 | |
|                     TextButton(
 | |
|                       onPressed: () => Navigator.of(ctx).pop(selected["NAME"]),
 | |
|                       child: const Text('确定'),
 | |
|                     ),
 | |
|                   ],
 | |
|                 ),
 | |
|               ),
 | |
|               const Divider(height: 1),
 | |
|               // 滚动选择器
 | |
|               Expanded(
 | |
|                 child: CupertinoPicker(
 | |
|                   scrollController: FixedExtentScrollController(
 | |
|                     initialItem: initialIndex,
 | |
|                   ),
 | |
|                   itemExtent: itemExtent,
 | |
|                   onSelectedItemChanged: (index) {
 | |
|                     selected = items[index];
 | |
|                   },
 | |
|                   // children: items.map(itemBuilder).toList(),
 | |
|                   children: List<Widget>.generate(items.length, (int index) {
 | |
|                     return Padding(
 | |
|                       // 通过Padding调整项间距
 | |
|                       padding: EdgeInsets.symmetric(
 | |
|                         vertical: desiredSpacing / 2,
 | |
|                       ),
 | |
|                       child: Center(
 | |
|                         child: Text(
 | |
|                           // '选项 $index',
 | |
|                           items[index]["NAME"],
 | |
|                           style: TextStyle(
 | |
|                             fontSize: 15,
 | |
|                             color:
 | |
|                                 index == selected
 | |
|                                     ? CupertinoColors.activeBlue
 | |
|                                     : CupertinoColors.inactiveGray,
 | |
|                             fontWeight:
 | |
|                                 index == selected
 | |
|                                     ? FontWeight.bold
 | |
|                                     : FontWeight.normal,
 | |
|                           ),
 | |
|                         ),
 | |
|                       ),
 | |
|                     );
 | |
|                   }),
 | |
|                 ),
 | |
|               ),
 | |
|             ],
 | |
|           ),
 | |
|         );
 | |
|       },
 | |
|     );
 | |
|   }
 | |
| }
 |