QinGang_interested/lib/customWidget/bottom_picker.dart

110 lines
3.3 KiB
Dart
Raw Normal View History

2025-12-12 09:11:30 +08:00
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
2026-04-08 15:03:56 +08:00
/// 选择结果(新增)
class PickerResult<T> {
final T value;
final int index;
PickerResult(this.value, this.index);
}
2025-12-12 09:11:30 +08:00
/// 通用底部弹窗选择器
class BottomPicker {
/// 显示底部选择器弹窗
///
2026-04-08 15:03:56 +08:00
/// [withIndex] = true 时返回 PickerResult<T>
/// [withIndex] = false 时返回 T兼容旧代码
static Future<dynamic> show<T>(
BuildContext context, {
required List<T> items,
required Widget Function(T item) itemBuilder,
int initialIndex = 0,
double itemExtent = 50.0,
double height = 250,
/// 新增参数
bool withIndex = false,
}) {
2025-12-12 09:11:30 +08:00
if (items.isEmpty) return Future.value(null);
final safeIndex = initialIndex.clamp(0, items.length - 1);
2026-04-08 15:03:56 +08:00
2025-12-12 09:11:30 +08:00
T selected = items[safeIndex];
2026-04-08 15:03:56 +08:00
int selectedIndex = safeIndex;
2025-12-12 09:11:30 +08:00
2026-04-08 15:03:56 +08:00
return showModalBottomSheet<dynamic>(
2025-12-12 09:11:30 +08:00
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();
},
2026-04-08 15:03:56 +08:00
child: const Text(
'取消',
style: TextStyle(color: Colors.black54, fontSize: 16),
),
2025-12-12 09:11:30 +08:00
),
TextButton(
onPressed: () {
FocusScope.of(context).unfocus();
2026-04-08 15:03:56 +08:00
if (withIndex) {
Navigator.of(ctx).pop(
PickerResult(selected, selectedIndex),
);
} else {
Navigator.of(ctx).pop(selected);
}
2025-12-12 09:11:30 +08:00
},
2026-04-08 15:03:56 +08:00
child: const Text(
'确定',
style: TextStyle(color: Colors.blue, fontSize: 16),
),
2025-12-12 09:11:30 +08:00
),
],
),
),
const Divider(height: 1),
2026-04-08 15:03:56 +08:00
2025-12-12 09:11:30 +08:00
// 滚动选择器
Expanded(
child: CupertinoPicker(
scrollController: FixedExtentScrollController(
initialItem: initialIndex,
),
itemExtent: itemExtent,
onSelectedItemChanged: (index) {
selected = items[index];
2026-04-08 15:03:56 +08:00
selectedIndex = index;
2025-12-12 09:11:30 +08:00
},
2026-04-08 15:03:56 +08:00
children: items
.map((item) => Center(child: itemBuilder(item)))
.toList(),
2025-12-12 09:11:30 +08:00
),
),
],
),
);
},
);
}
2026-04-08 15:03:56 +08:00
}