时间:2022-06-13 10:14:34 | 栏目:Android代码 | 点击:次
单选版可看上篇博文 用flutter封装一个点击菜单工具栏组件
本文是CHeckbox多选版
效果如图所示,点击选项回调选中的index和是否选中的值,可以自定义横向纵向,传递宽高后自动计算子项宽高,自定义边框、背景、选中的样式
第一部分是封装子项组件, ToolMenuCheckboxItemWidget组件如下:
import 'dart:core'; import 'package:flutter/material.dart'; /// @author 编程小龙 /// @创建时间:2022/3/8 /// 工具菜单checkbox版子项 class ToolMenuCheckboxItemWidget extends StatelessWidget { /// 显示的title final String title; /// 序号 final int index; /// 点击回调 final void Function(int, bool) click; final double width; final double height; final bool isActive; final bool isHorizontal; // 是否横向 final bool isEnd; // 是否为末尾 final Color? activeColor; // 点击后的颜色 没传取主题色 final Color? backgroundColor; // 背景色 final Color? borderColor; // 边框色 final TextStyle? textStyle; // 文字样式 final TextStyle? activeTextStyle; // 选中的文字样式 const ToolMenuCheckboxItemWidget( {Key? key, this.isActive = false, required this.title, required this.index, required this.click, this.isHorizontal = false, this.width = 100, this.isEnd = false, this.height = 40, this.activeColor, this.backgroundColor, this.borderColor, this.textStyle, this.activeTextStyle}) : super(key: key); @override Widget build(BuildContext context) { TextStyle defaultTextStyle = TextStyle( fontSize: 16, color: isActive ? Colors.white : Colors.black87); return Material( child: Ink( // 点击右波纹效果 width: width, height: height, decoration: BoxDecoration( color: isActive ? activeColor ?? Theme.of(context).primaryColor : backgroundColor ?? Colors.white30, border: isHorizontal ? isEnd ? const Border() : Border( right: BorderSide( width: 1, color: borderColor ?? Colors.grey)) : Border( bottom: BorderSide( width: 1, color: borderColor ?? Colors.grey))), child: InkWell( onTap: () { click(index,!isActive); }, child: Center( child: Text(title, style: isActive ? activeTextStyle ?? defaultTextStyle : textStyle ?? defaultTextStyle), )), ), ); } }
第二部分是封装菜单内容,ToolMenuCheckBoxWidget代码如下
import 'package:demo/widgets/tool_menu_checkbox_item_widget.dart'; import 'package:flutter/material.dart'; /// @author 编程小龙 /// @创建时间:2022/3/8 /// 工具菜单checkbox版 class ToolMenuCheckBoxWidget extends StatefulWidget { final Map<String, bool> items; // title:checked 的形式 返回值为 key:true/false final void Function(int, bool) click; // 点击回调 返回第n个的选中情况 final double? width; final double? height; final bool isHorizontal; // 横向 final Color? activeColor; // 点击后的颜色 没传取主题色 final Color? backgroundColor; // 背景色 final Color? borderColor; // 边框色 final TextStyle? textStyle; // 文字样式 final TextStyle? activeTextStyle; // 选中的文字样式 const ToolMenuCheckBoxWidget( {Key? key, required this.items, required this.click, this.width, this.height, this.isHorizontal = false, this.activeColor, this.backgroundColor, this.borderColor, this.textStyle, this.activeTextStyle}) : super(key: key); @override State<ToolMenuCheckBoxWidget> createState() => _ToolMenuCheckBoxWidgetState(); } class _ToolMenuCheckBoxWidgetState extends State<ToolMenuCheckBoxWidget> { late Map<String, bool> items; bool isHorizontal = false; // 是否横向 @override void initState() { // 初始化当前选中 items = widget.items; isHorizontal = widget.isHorizontal; super.initState(); } @override Widget build(BuildContext context) { int index = 0; // 遍历自增 index int size = widget.items.length; double height = widget.height ?? (isHorizontal ? 50 : 200); // 设置水平和竖直时的默认值 double width = widget.width ?? (isHorizontal ? 400 : 100); return Container( height: height, width: width, decoration: BoxDecoration( color: widget.backgroundColor ?? Colors.white30, border: Border.all(color: widget.borderColor ?? Colors.grey, width: 1), ), child: Wrap( children: items.keys.map((key) { return ToolMenuCheckboxItemWidget( title: key, index: index, isHorizontal: widget.isHorizontal, click: (index, isChecked) { setState(() { items[key] = isChecked; }); widget.click(index, isChecked); }, height: widget.isHorizontal ? height - 2 : height / size, isActive: items[key] ?? false, width: widget.isHorizontal ? width / size - 1 : width, isEnd: index++ == size - 1, textStyle: widget.textStyle, activeTextStyle: widget.activeTextStyle, backgroundColor: widget.backgroundColor, activeColor: widget.activeColor, borderColor: widget.borderColor, ); }).toList(), ), ); } }
最简单案例只需传入titles即可,选中颜色默认取主题颜色,后续再弄一个chekbox版的,可多选菜单
/// 竖向 ToolMenuCheckBoxWidget( items: { // 注意这里map不要用const声明,因为里面的值传递过去会同步更改,并不会重新copy一份值操作 "选项1": true, "选项2": true, "选项3": false, "选项4": false }, click: (index, isActive) { print("竖向 选项$index 的值为$isActive"); }), /// 自定义样式横向 ToolMenuCheckBoxWidget( items: { // 注意这里map不要用const声明,因为里面的值传递过去会同步更改,并不会重新copy一份值操作 "选项1": true, "选项2": false, "选项3": false, "选项4": true, "选项5": false, "选项6": false, }, click: (index, isActive) { print("横向 选项$index 的值为$isActive"); }, isHorizontal: true, activeColor: Colors.green, backgroundColor: Colors.black, textStyle: const TextStyle(color: Colors.white), activeTextStyle: const TextStyle(color: Colors.white, fontSize: 18), borderColor: Colors.orange, ),