flutter 自己定义多选

自定义多选:

2022-06-19 22:48:57 星期日

新学的flutter 对各种的语法和代码技巧不是很熟练。没有考虑那么多的自定义话编辑,只是简单的进行的了一个多选组建的封装,符合目前的我需要的逻辑。
仅供新手参考。希望大家多多指导

预览

image


实现 多选中的 每一项的代码:

点击查看代码
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;
  }
}

###
posted @ 2022-06-19 23:04  大脚-  阅读(355)  评论(0编辑  收藏  举报