Flutter通用UI之FlowLayout

效果图:

在这里插入图片描述

功能详解:

FlowLayout支持边框颜色,边框圆角,选中背景色,未选中背景色,选中字体色值,未选中字体色值,字体大小,控件间距,选择个数

代码部分:

import 'package:flutter/material.dart';

class FlowLayout extends StatefulWidget {
  final List<String> list; //数据源
  final Color unSelectedColor; //初始背景色
  final Color selectColor; //选中时背景色
  final OnItemClickListener listener;
  final Color unSelectedBorderSlideColor; //未选中时边框色值
  final Color selectedBorderSlideColor; //选中时边框色值
  final int maxSelectSize; //最多选择的个数
  final double borderRadius; //边框圆角
  final double textSize; //字体大小
  final Color selectedTextColor; //选中时字体色值
  final Color unSelectTextColor; //未选中时字体色值
  final double marge; //间距

  FlowLayout(
      {@required this.list,
      this.unSelectedColor,
      this.selectColor,
      this.unSelectedBorderSlideColor,
      this.selectedBorderSlideColor,
      this.maxSelectSize,
      this.borderRadius,
      this.textSize,
      this.selectedTextColor,
      this.unSelectTextColor,
      this.marge,
      this.listener});

  @override
  _FlowLayoutState createState() => _FlowLayoutState(
      list: list,
      unSelectedColor: unSelectedColor,
      selectColor: selectColor,
      unSelectedBorderSlideColor: unSelectedBorderSlideColor,
      selectedBorderSlideColor: selectedBorderSlideColor,
      maxSelectSize: maxSelectSize,
      borderRadius: borderRadius,
      listener: listener);
}

class _FlowLayoutState extends State<FlowLayout> {
  List<String> list;
  Color unSelectedColor;
  Color selectColor;
  Color unSelectedBorderSlideColor;
  Color selectedBorderSlideColor;
  int maxSelectSize;
  double borderRadius;
  double textSize;
  Color selectedTextColor;
  Color unSelectTextColor;
  double marge;

  OnItemClickListener listener;
  List<String> selectList = List<String>();
  List<int> selectIndexList = List<int>();

  _FlowLayoutState(
      {@required this.list,
      this.unSelectedColor,
      this.selectColor,
      this.unSelectedBorderSlideColor,
      this.selectedBorderSlideColor,
      this.maxSelectSize,
      this.borderRadius,
      this.textSize,
      this.selectedTextColor,
      this.unSelectTextColor,
      this.marge,
      this.listener});

  @override
  Widget build(BuildContext context) {
    return Wrap(
      direction: Axis.horizontal, //主轴的方向
      spacing: marge ?? 5, // 主轴方向的间距
      children: _buildListWidget(list, maxSelectSize),
    );
  }

  List<Widget> _buildListWidget(List<String> list, int maxSize) {
    var listWidget = List<Widget>();
    for (var i = 0; i < list.length; i++) {
      if (selectIndexList.length > 0) {
        if (selectIndexList.contains(i)) {
          listWidget.add(_buildSingleText(list[i], i, true, maxSize));
        } else {
          listWidget.add(_buildSingleText(list[i], i, false, maxSize));
        }
      } else {
        listWidget.add(_buildSingleText(list[i], i, false, maxSize));
      }
    }

    return listWidget;
  }

  Widget _buildSingleText(String item, int index, bool select, int maxSize) {
    var _maxSelectSize = maxSize ?? 0;
    var text;
    if (select) {
      text = _buildSpecialWidget(item);
    } else {
      text = _buildNormalWidget(item);
    }

    return GestureDetector(
      child: text,
      onTap: () {
        var set = new Set();
        set.addAll(selectList);

        if (_maxSelectSize == set.toList().cast().length) {
          if (!selectIndexList.contains(index)) {
            return;
          } else {
            setSelectData(index, select);
          }
        } else {
          setSelectData(index, select);
        }
      },
    );
  }

  setSelectData(int index, bool select) {
    setState(() {
      if (select) {
        selectList.remove(list[index]);
        selectIndexList.remove(index);
        listener.onItemClick(selectList);
      } else {
        selectList.add(list[index]);
        selectIndexList.add(index);
        listener.onItemClick(selectList);
      }
    });
  }

  /*点击时widget*/
  Widget _buildSpecialWidget(String desc) {
    return Chip(
      label: Text(
        desc,
        style: TextStyle(
            color: selectedTextColor ?? Color(0xff343a40),
            fontSize: textSize ?? 14),
      ),
      backgroundColor: selectColor ?? Colors.white,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(borderRadius ?? 8),
          side: BorderSide(
              color: selectedBorderSlideColor ?? Colors.yellow, width: 1)),
    );
  }

/*未点击时widget*/
  Widget _buildNormalWidget(String desc) {
    return Chip(
      label: Text(desc,
          style: TextStyle(
              color: selectedTextColor ?? Color(0xff343a40),
              fontSize: textSize ?? 14)),
      backgroundColor: unSelectedColor ?? Color(0xFFD6D6D6),
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(borderRadius ?? 8.0),
          side: BorderSide(
              color: unSelectedBorderSlideColor ?? Colors.transparent,
              width: 1)),
    );
  }
}

abstract class OnItemClickListener {
  onItemClick(List<String> list);
}

代码调用

class FlowLayoutRouter extends StatelessWidget implements OnItemClickListener {
  List<String> list = ["乒乓球", "篮球", "羽毛球", "棒球", "是你的就是你的","我的还是我的"];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter",
      home: Scaffold(
        body: Padding(
          padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
          child: FlowLayout(
            list: list,
            listener: this,
            selectColor: Colors.yellow,
            maxSelectSize: 9,
          ),
        ),
      ),
    );
  }

  @override
  onItemClick(List<String> text) {
    print("最终选择的" + text.toString());
  }
}

重要部分

调用:

   child: FlowLayout(
            list: list,
            listener: this,
            selectColor: Colors.yellow,
            maxSelectSize: 2,
          ),

回调:

 @override
  onItemClick(List<String> text) {
    print("最终选择的" + text.toString());
  }

属性含义

属性含义
list数据源
unSelectedColor初始背景色
selectColor选中背景色
selectColor回调
unSelectedBorderSlideColor未选中时边框色值
selectedBorderSlideColor选中时边框色值
maxSelectSize最多选择个数
borderRadius边框圆角
textSize字体大小
selectedTextColor选中时字体色值
unSelectTextColor未选中时字体色值
marge控件之间间距

Demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值