Flutter 基于ChoiceChip的标签选择控件

1.ChoiceChip

ChoiceChip 选择控件,可以实现单选效果

先看对应的属性

 const ChoiceChip({
    Key key,
    this.avatar, //左侧Widget 一般小图标
    @required this.label, //标签文字
    this.labelStyle, //标签文字的样式
    this.labelPadding, 
    this.onSelected, 
    this.pressElevation, 
    @required this.selected, //是否选中
    this.selectedColor, //选择的颜色
    this.disabledColor, //不可用的颜色
    this.tooltip, 
    this.shape, //shape 默认是两端半圆形
    this.clipBehavior = Clip.none,
    this.backgroundColor, //背景色
    this.padding, 
     //设置为MaterialTapTargetSize.shrinkWrap时
     //,clip距顶部距离为0;设置为MaterialTapTarget
     //Size.padded时距顶部有一个距离
    this.materialTapTargetSize,
    this.elevation,
    this.shadowColor,//阴影背景色
    this.selectedShadowColor,//选中的阴影背景色
    this.avatarBorder = const CircleBorder(),
  })

默认的情况下,ChoiceChip 选择主要是修改背景色以及对应的文字,

2.封装代码

MultiNormalSelectChip封装ChoiceChip完成标签选择

//提供tag基本类
abstract class BaseSelectEntity{
  String getTag();
}


class MultiNormalSelectChip<T extends BaseSelectEntity> extends StatefulWidget {
  /// 标签的list
  final List<T> dataList;

  /// 标签的list
  final List<T> selectList;

  ///选择回调事件
  final Function(List<T>) onSelectionChanged;

  MultiNormalSelectChip(this.dataList, {this.selectList, this.onSelectionChanged});

  @override
  _MultiNormalSelectChipState createState() => _MultiNormalSelectChipState(selectList);
}

class _MultiNormalSelectChipState<T extends BaseSelectEntity>
    extends State<MultiNormalSelectChip> {
  List<T> selectList;

  _MultiNormalSelectChipState(this.selectList);

  _buildChoiceList() {
    List<Widget> choices = List();
    widget.dataList.forEach((item) {
      choices.add(Container(
        height: 31,
        padding: EdgeInsets.all(4),
        child: ChoiceChip(
          label: Text(
            item.getTag(),
            style: TextStyle(fontSize: 14),
          ),
          selected: selectList.contains(item),
          materialTapTargetSize: MaterialTapTargetSize.padded,
          labelPadding: EdgeInsets.only(bottom: 9),
          padding: EdgeInsets.only(left: 12, right: 12, bottom: 9),
          selectedColor: Colors.white,
          backgroundColor: Colors.blue,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12),
            side: BorderSide(color: Colors.black, width: 0.5),
          ),
          onSelected: (selected) {
            setState(() {
              selectList.contains(item)
                  ? selectList.remove(item)
                  : selectList.add(item);
              widget.onSelectionChanged(selectList);
            });
          },
        ),
      ));
    });

    return choices;
  }

  @override
  Widget build(BuildContext context) {
    return Wrap(
      alignment: WrapAlignment.end,
      children: _buildChoiceList(),
    );
  }
}


定义个基本实体类,BaseSelectEntity,提供getTag方法返回标签的label,之后根据传进来的list,遍历生成对应的choiceChip即可完成标签选择。然后通过回调函数onSelected 设置对应的选中的item 存入selectList中
其效果如下:

image

3.修改原有的ChoiceChip

然而公司UI给的图确实这样的,这种情况下,就需要修改ChoiceChip源码,增加selectShape属性

BorderChoiceChip(
          label: Text(
            item.getTag(),
            style: TextStyle(fontSize: 14),
          ),
          selected: selectList.contains(item),
          materialTapTargetSize: MaterialTapTargetSize.padded,
          labelPadding: EdgeInsets.only(bottom: 9),
          padding: EdgeInsets.only(left: 12, right: 12, bottom: 9),
          selectedColor: Colors.white,
          backgroundColor: Colors.white,
          //修改边框样式
          selectShape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12),
            side: BorderSide(color: Colors.blue, width: 0.5),
          ),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12),
            side: BorderSide(color: Colors.black, width: 0.5),
          ),
          onSelected: (selected) {
            setState(() {
              selectList.contains(item)
                  ? selectList.remove(item)
                  : selectList.add(item);
              widget.onSelectionChanged(selectList);
            });
          },

这样就可以达到相对应的要求,效果如下


image

具体的代码,可以查看 demo

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,148评论 1 32
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,770评论 1 45
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,187评论 6 13
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,869评论 2 9
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,694评论 0 4