16.2 选择器封装

16.2 选择器封装

实现步骤:


封装组件有一个原则,按需要封装,逐步完善,丰富功能

第 1 步:安装 flutter_picker modal_bottom_sheet 插件

pubspec.yaml

1
2
3
4
5
dependencies:
# picker 选择器
flutter_picker: 2.0.3
# 底部弹出
modal_bottom_sheet: 2.0.1

第 2 步:根据 array 数据生成选着器

lib/common/utils/picker.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import 'package:flutter/material.dart';
import 'package:flutter_picker/Picker.dart';
import 'package:flutter_woo_commerce_getx_learn/common/index.dart';

/// picker 选取器
class ActionPicker {
/// 选取器 array , 多列
static Picker array({
required PickerAdapter adapter,
List<int>? selecteds,
}) {
return Picker(
/// 数据项高度
itemExtent: 40,

/// 选取器高度
height: 270,

/// 背景色
backgroundColor: Colors.transparent,

/// 容器颜色
containerColor: Colors.transparent,

/// 头部栏位隐藏
hideHeader: true,

/// 文字样式
textStyle: TextStyle(
fontSize: 18,
height: 1.2,
color: AppColors.secondary,
// color: AppColors.,
),

/// 数据适配器
adapter: adapter,

/// 选中项 [index]
selecteds: selecteds,
);
}
}

第 3 步:底部弹出对话框

lib/common/utils/bottom_sheet.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import 'package:flutter/material.dart';
import 'package:flutter_picker/Picker.dart';
import 'package:get/get.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';

import '../index.dart';

/// 底部弹出对话框
class ActionBottomSheet {
// 头部
static Widget _buildHeader({
/// 标题
String? title,

/// 确认事件
Function()? onConfirm,
}) {
return <Widget>[
// title
TextWidget.title2(title ?? '').expanded(),

// done 按钮
ButtonWidget.text(
LocaleKeys.commonBottomApply.tr,
onTap: onConfirm,
),
].toRow().padding(
left: 10,
top: 10,
right: 10,
);
}

/// 数据对话框
static void data({
/// 上下文 context
required BuildContext context,

/// 确认事件
required Function(List value) onConfirm,

/// 选取器数据适配器
required PickerAdapter adapter,

/// 标题
String? title,

/// 默认选中 [index]
List<int>? selecteds,
}) {
// 准备 picker
var picker = ActionPicker.array(
adapter: adapter,
selecteds: selecteds,
);

// 调用 标准模式框
normal(
context: context,
contentPadding: const EdgeInsets.all(0),
child: <Widget>[
// 头部栏
_buildHeader(
title: title,
onConfirm: () {
picker.doConfirm(context);
onConfirm(picker.adapter.getSelectedValues());
},
),
// picker 内容
picker.makePicker(),
].toColumn(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
),
);
}

// 标准 - 底部弹出 - 模式对话框
static Future<void> normal({
required BuildContext context,
Widget? child,
EdgeInsetsGeometry? contentPadding,
bool enableDrag = true,
}) async {
/// 弹出底部模式对话框
return await showMaterialModalBottomSheet(
// 上下文 context
context: context,
// 背景透明
backgroundColor: Colors.transparent,
// 启用拖拽
enableDrag: enableDrag,
// 内容
builder: (context) => SafeArea(
minimum: const EdgeInsets.all(10),
child: AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 150),
child: Container(
padding: contentPadding ?? const EdgeInsets.all(10),
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
// 弹出视图内容区
child: child,
),
),
),
);
}

// Bar 对话框
static Future<void> barModel(
Widget child, {
BuildContext? context,
double? padding,
bool enableDrag = true,
}) async {
/// 弹出底部模式对话框
return await showBarModalBottomSheet(
// 上下文 context
context: context ?? Get.context!,
// 背景透明
backgroundColor: Colors.transparent,
// 启用拖拽
enableDrag: enableDrag,
// expand
expand: false,
// 内容
builder: (context) => SafeArea(
child: child,
),
// builder: (context) =>
// SafeArea(child: child.paddingAll(padding ?? AppSpace.card)
// .decorated(
// color: AppColors.background,
// borderRadius: BorderRadius.circular(AppRadius.sheet),
// )
// .clipRRect(
// clipBehavior: Clip.antiAlias,
// topLeft: AppRadius.sheet,
// topRight: AppRadius.sheet,
// ),
// ),
);
}

// 底部弹出 popModal
static Future<void> popModal({
BuildContext? context,
required Widget child,
EdgeInsetsGeometry? contentPadding,
EdgeInsets? safeAreaMinimum,
}) async {
return await showMaterialModalBottomSheet(
context: context ?? Get.context!,
backgroundColor: Colors.transparent,
builder: (context) => SafeArea(
minimum: safeAreaMinimum ?? EdgeInsets.zero,
child: child,
),
);
}
}

提交代码到 git