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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章