实现如截图所示的 多选功能
实现代码:
实现 多选中的 每一项的代码:
import 'dart:core';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter/material.dart';
/// @author XCC
/// @创建时间:2022/5/9
/// 工具菜单checkbox版子项
class ToolMenuCheckboxItemWidget extends StatelessWidget {
/// 显示的title
final String title;
final int value;
/// 点击回调
final Function click;
final double? width;
final double? height;
final bool isActive;
final Color? backgroundColor; // 未选中背景色
final Color? activeBackgroundColor; // 选中的的颜色 没传取主题色
final BoxBorder? activeBorder; // 选中的border
final BorderRadiusGeometry? borderRadius; // 圆角
final TextStyle? textStyle; // 文字样式
final TextStyle? activeTextStyle; // 选中的文字样式
const ToolMenuCheckboxItemWidget(
{Key? key,
this.isActive = false,
required this.title,
required this.click,
required this.value,
this.width,
this.height,
this.activeBackgroundColor,
this.backgroundColor,
this.activeBorder,
this.borderRadius,
this.textStyle,
this.activeTextStyle})
: super(key: key);
@override
Widget build(BuildContext context) {
TextStyle defaultTextStyle = const TextStyle();
double defaultWidth = width ?? 100.w;
double defaultHeight = height ?? 50.w;
return Container(
// 点击右波纹效果
width: defaultWidth,
height: defaultHeight,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
border: !isActive
? Border.all(width: 1.w, color: Colors.transparent)
: activeBorder,
borderRadius: borderRadius ?? BorderRadius.circular(defaultHeight / 2),
),
child: Material(
color: isActive
? activeBackgroundColor ?? Theme.of(context).primaryColor
: backgroundColor ?? Colors.white60,
borderRadius: borderRadius ?? BorderRadius.circular(defaultHeight / 2),
child: Ink(
child: InkWell(
onTap: () {
click(value);
},
child: Center(
child: Text(title,
style: isActive
? activeTextStyle ?? defaultTextStyle
: textStyle ?? defaultTextStyle),
),
),
),
),
);
}
}
实现多选组件的代码:
import 'dart:core';
import 'package:communityApp/home_system/components/check_box_widget/tool_menu_check_box_item_widget.dart';
import 'package:communityApp/home_system/models/recommendToday.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter/material.dart';
/// @author XCC
/// @创建时间:2022/5/9
/// 工具菜单checkbox版
class ToolMenuCheckBoxWidget extends StatefulWidget {
final List<FindSimilarYouWant> children;
final Function click; // 点击回调 返回第n个的选中情况
final double? width; //item 宽
final double? height; // item 高
final List? selectList; // 选中的数据
final Color? backgroundColor; // 背景色
final Color? activeBackgroundColor; // 选中的背景颜色
final BoxBorder? activeBorder; // 选中的边框
final BorderRadiusGeometry? borderRadius; // 圆角
final TextStyle? textStyle; // 文字样式
final TextStyle? activeTextStyle; // 选中的文字样式
const ToolMenuCheckBoxWidget(
{Key? key,
required this.children,
required this.click,
this.width,
this.height,
this.activeBackgroundColor,
this.activeBorder,
this.selectList,
this.backgroundColor,
this.borderRadius,
this.textStyle,
this.activeTextStyle})
: super(key: key);
@override
State<ToolMenuCheckBoxWidget> createState() => _ToolMenuCheckBoxWidgetState();
}
class _ToolMenuCheckBoxWidgetState extends State<ToolMenuCheckBoxWidget> {
late List<FindSimilarYouWant> items;
late final List _selctedList = widget.selectList ?? [];
@override
void initState() {
// 初始化当前选中
items = widget.children;
super.initState();
}
// 是否选中
bool eachItems(val) {
bool falg = false;
for (var ele in _selctedList) {
if (ele == val) {
falg = true;
}
}
return falg;
}
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 10.w,
runSpacing: 10.w,
alignment: WrapAlignment.start,
children: widget.children.map((val) {
return ToolMenuCheckboxItemWidget(
title: val.title,
value: val.value,
click: (int selectValue) {
// bool galg = false;
// setState(() {
// _selctedList.removeWhere((element) {
// galg = true;
// return element == selectValue;
// });
// if (!galg) {
// setState(() {
// _selctedList.add(val.value);
// });
// }
// });
if (_selctedList.contains(selectValue)) {
setState(() {
_selctedList.remove(selectValue);
});
} else {
setState(() {
_selctedList.add(selectValue);
});
}
widget.click(_selctedList);
},
width: widget.width,
height: widget.height,
isActive: eachItems(val.value),
backgroundColor: widget.backgroundColor,
textStyle: widget.textStyle,
activeTextStyle: widget.activeTextStyle,
activeBackgroundColor: widget.activeBackgroundColor,
activeBorder: widget.activeBorder,
borderRadius: widget.borderRadius,
);
}).toList(),
);
}
}
试用的代码:
///初始化代码
widget.selectlist = [];
var data = [
{"title": 'aaa', "value": 1},
{"title": 'bbb', "value": 2},
{"title": 'ccc', "value": 3},
{"title": 'ddd', "value": 4},
];
youList = data.map((e) => FindSimilarYouWant.froJson(e)).toList();
builder 的代码
ToolMenuCheckBoxWidget(
width: 105.w,
height: 36.w,
children: youList, ///数据列表
selectList: widget.selectlist, ///默认选中的代码
backgroundColor: const Color(0xFFF3F9FB),
activeBackgroundColor: Colors.white,
activeBorder:
Border.all(width: 1.w, color: const Color(0xFFFF8A00)),
activeTextStyle: TextStyle(
color: const Color(0xFFFF8A00),
fontSize: 14.sp,
fontWeight: FontWeight.w500,
),
textStyle: TextStyle(fontSize: 14.sp),
click: (List selection) {
setState(() {
widget.selectlist = selection; ///接受选中的数据
});
print('======>$selection');
},
)
EndTip:
在传递 children 这个Map 列表,进行map遍历去拿到Map里数据的时候 , 会出现数据格式报错的问题 (超级恶心的问题!!!!),我写了一个models来对传递的children数据 进行类型声明。
代码:
class FindSimilarYouWant {
late String title;
late int value;
FindSimilarYouWant({required this.title, required this.value});
FindSimilarYouWant.froJson(Map<String, dynamic> json) {
title = json['title'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['title'] = title;
data['value'] = value;
return data;
}
}