84 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.5 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 = 40.0,
 | |
|         double height = 250,
 | |
|       }) {
 | |
|     // 当前选中项
 | |
|     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: 30,
 | |
|                   onSelectedItemChanged: (index) {
 | |
|                     selected = items[index];
 | |
|                   },
 | |
|                   children: items.map(itemBuilder).toList(),
 | |
|                 ),
 | |
|               ),
 | |
|             ],
 | |
|           ),
 | |
|         );
 | |
|       },
 | |
|     );
 | |
|   }
 | |
| }
 |