[》跳过拾光记忆]
拾光记忆
1. Flutter 项目资产管理,看这一篇就够了!
简介: 针对 Flutter 项目资产管理的脚本服务。Fam 具有以下特点: 支持多种平台以及各平台无差异化、界面美观、功能齐全、快捷方便。
推荐: ⭐️⭐️⭐️⭐️⭐️
2. Flutter 手势在多指触摸时一些方法会多次触发
简介: 针对 Flutter 多手指检测以及手势触发其他手势也触发的问题。
推荐: ⭐️⭐️⭐️⭐️⭐️
3. Dart 的枚举类型的高阶用法
简介: 这是让开发者更深入的了解 Dart 的枚举以及相关使用和方法。
推荐: ⭐️⭐️⭐️
[返回拾光记忆《]
一、选择简述
在使用 Flutter 开发中,业务需求往往是多种多样的,比如:常见的一个需求就是进行单项或者多项选择的需求。然而,Flutter 并没有给我们提供便捷的实现方式或者组件。我们要自己在项目中去实现这个功能,肯定需要耗费很多时间以及精力。但是,好的消息是 Pub.dev
上的 idkit 开发包为开发者提供了这样功能的组件,该小部件是 IDKitChoice。
二、IDKitChoice 的介绍
IDKitChoice 是 Flutter 业务开发中能便捷实现 单选 或 多选 的快捷小部件。
- IDKitChoice 提供了四种初始化的方法,如下:
可根据自己软件的视图设计选择对应的方法快捷实现选择。1. const IDKitChoice.list(xx) 2. const IDKitChoice.listSeparated(xx) 3. const IDKitChoice.grid(xx) 4. const IDKitChoice.warp(xx)
- IDKitChoice 可以设置多选最大选择数量
控制选择最大数量的属性是int? maximumChoice
。 - IDKitChoice 可以设置选择后是否可以完全取消
控制选择是否能完全取消的属性是bool isCancelAll = true
。 - IDKitChoice 可以设置初始是否选择回调
控制初始是否选择回调的属性是bool isStartChoicedCall = false
。 - IDKitChoice 可以设置初始选择的对象
控制初始选择对象的属性是List<int>? chosenIndexs
。 - IDKitChoice 可以便捷的实现单选和多选的切换
控制单选和多选的切换属性是ChoiceType type = ChoiceType.single
。
三、IDKitChoice 的配置
IDKitChoice 是 idkit 包里面的小部件。idkit 依托于 pub.dev 进行管理。所以我们可以使用下面指令在项目的根目录执行来添加idkit包,指令如下: flutter pub add idkit
。如下图所示:
或者可以拷贝 pub.dev 上的 idkit 的使用版本,如下下图所示:
将考本的文本添加到 Flutter 项目的 pubspec.yaml 文件的 dependencies 标签下,如上图所示,然后需要执行
flutter pub get
指令拉取 idkit 包。
四、IDKitChoice 的应用
1. 单选 -- 性别选择
数据源如下:
/// 性别
static List<Map<String, dynamic>> sexList = [
{
'label': '未知',
'tag': 0,
},
{
'label': '男',
'tag': 1,
},
{
'label': '女',
'tag': 2,
}
];
实例应用代码如下:
SizedBox(
height: 40,
child: IDKitChoice<Map<String, dynamic>>.warp(
direction: Axis.vertical,
isCancelAll: true,
runSpacing: 10,
sources: ChooseConfig.sexList,
choiceCallMethod: (result, results) {
print(result);
},
itemBuilder: (context, state, data) {
return Row(
children: [
Icon(
state
? Icons.radio_button_checked
: Icons.radio_button_off,
size: 20,
),
5.hGap,
Text(data['label'] as String)
],
);
},
).insetsSymmetric(vertical: 10),
)
实现效果如下:
从上图可以看出,我们可以完全自定义选中和未选中的视图样式。
2. 多选 -- 多标签选择
选择数据源:
/// 标签
static List<Map<String, dynamic>> markList = [
{
'label': '善良勤恳',
'tag': 0,
},
{
'label': '美丽身材好',
'tag': 1,
},
{
'label': '落落大方',
'tag': 2,
},
{
'label': '可爱动人',
'tag': 3,
},
{
'label': '妖娆妩媚迷人',
'tag': 4,
},
];
应用代码如下:
IDKitChoice.warp(
spacing: 10,
runSpacing: 10,
sources: ChooseConfig.markList,
type: ChoiceType.multiple,
maximumChoice: 3,
itemBuilder: (context, state, data) {
return Container(
decoration: BoxDecoration(
color: state ? Colors.green : Colors.grey,
borderRadius: BorderRadius.circular(6),
),
child: Text(data['label'])
.insetsSymmetric(horizontal: 5, vertical: 3),
);
},
),
效果显示如下:
3. 单选 -- 侧边选择列表
数据源如下:
/// 测列表切换
static List<Map<String, dynamic>> sildeList = [
{
'label': '北京市',
'tag': 0,
},
{
'label': '朝阳区',
'tag': 1,
},
{
'label': '西城区',
'tag': 2,
},
{
'label': '东城区',
'tag': 3,
},
{
'label': '通州区',
'tag': 4,
},
];
应用实例代码如下:
const Text('侧列表切换:').insetsOnly(top: 30, bottom: 10),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(10),
),
height: 300,
child: Row(
children: [
SizedBox(
width: 120,
child: IDKitChoice.list(
sources: ChooseConfig.sildeList,
choiceCallMethod: (result, results) {
silderStreamController.add(result['label']);
},
itemBuilder: (context, state, data) {
return Container(
color: state ? Colors.red : Colors.white,
child: Text(data['label']),
);
},
),
),
const VerticalDivider(
color: Colors.grey,
),
Expanded(
child: StreamBuilder(
initialData: '请选择区域',
stream: silderStreamController.stream,
builder: (context, snapshot) {
return Center(child: Text(snapshot.data!));
},
),
),
],
).insetsAll(10),
).insetsOnly(right: 10)
实现效果如下:
4. 单选 -- TabBar的选择
选择的数据源:
/// Tabbar 的切换
static List<Map<String, dynamic>> tabbarList = [
{
'label': '早间新闻',
'tag': 0,
},
{
'label': '今日热榜',
'tag': 1,
},
{
'label': '视频号',
'tag': 2,
},
{
'label': '咨询',
'tag': 3,
},
{
'label': '抖音短视频',
'tag': 4,
},
];
用于实例的代码:
const Text('Tabbarde 的切换:').insetsOnly(top: 30, bottom: 10),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
SizedBox(
height: 44,
child: IDKitChoice.list(
scrollDirection: Axis.horizontal,
sources: ChooseConfig.tabbarList,
choiceCallMethod: (result, results) {
silderStreamController.add(result['label']);
},
itemBuilder: (context, state, data) {
return Center(
child: Text(
data['label'],
style: TextStyle(
decorationColor:
state ? Colors.red : Colors.transparent,
decorationThickness: state ? 3 : 0,
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.solid,
),
).insetsSymmetric(horizontal: 10),
);
},
),
),
SizedBox(
height: 100,
child: StreamBuilder(
initialData: '请选择区域',
stream: silderStreamController.stream,
builder: (context, snapshot) {
return Center(child: Text(snapshot.data!));
},
),
)
],
),
).insetsOnly(right: 10)
代码效果展示如下: