自定義多選:
2022-06-19 22:48:57 星期日
新學的flutter 對各種的文法和代碼技巧不是很熟練。沒有考慮那麼多的自定義話編輯,隻是簡單的進行的了一個多選組建的封裝,符合目前的我需要的邏輯。
僅供新手參考。希望大家多多指導
預覽
實作 多選中的 每一項的代碼:
點選檢視代碼
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;
}
}
###