Flutter 自定义控件 仿 IOS UISegment

效果图:

UISegment 在客户端开发中是很常用的组件,在Android 中我们可以用RadioButton来模仿效果。在flutter中也可以自己自定义一个模仿效果。

参数类型用途描述是否必须
titleNamesList<String>按钮名字的集合必须传
defaultColorColor选中item文字颜色 (这里默认Colors.white)可不传
selectedColorColor选中item背景色以及边框色 (这里默认Colors.black)

可不传

textSize

double字体大小(字体大小默认=13)可不传

selectItem

int初始选中的item(默认第一个)可不传

onSelectChanged

Function(int)

按钮点击回到方法 返回的是点击按钮的position 必须传
itemHeightdouble按钮高度 (默认=30)可不传
itemWidthdouble按钮宽度(默认=110)可不传
borderWidthdouble按钮边框宽度(默认=1)可不传
radiusdouble左右那妞的圆角 (默认 =5)可不传

 

 

 

 

 

 

 

 

 

 

 

源码:

import 'package:flutter/material.dart';

class SegmentBar extends StatefulWidget {
  //按钮名字集合
  final List<String> titleNames;
  //默认颜色
  final Color defaultColor;
  //选中时的颜色
  final Color selectedColor;
  //字体大小
  final double textSize;
  //初始时选中的item ,默认第一个
  final int selectItem;
  //点击回调
  final Function(int) onSelectChanged;
  //按钮高度
  final double itemHeight;
  //按钮宽度
  final double itemWidth;
  //按钮边框宽度
  final double borderWidth;
  //按钮圆角角度大小
  final double radius;

  SegmentBar(
      {@required this.titleNames,
      @required this.onSelectChanged,
      this.defaultColor = Colors.white,
      this.selectedColor = Colors.black,
      this.textSize = 13,
      this.itemHeight = 30,
      this.itemWidth = 110,
      this.borderWidth = 1,
      this.radius = 5,
      this.selectItem = 0});

  @override
  _SegmentBarState createState() => _SegmentBarState();
}

class _SegmentBarState extends State<SegmentBar> {
  int selectItem;
  @override
  void initState() {
    super.initState();
    selectItem = widget.selectItem;
  }

  _buildSegmentItems(List list) {
    if (list == null && list.isEmpty) {
      return Container();
    }
    List<Widget> items = List();
    for (var i = 0; i < list.length; i++) {
      Widget item = Container(
        padding: EdgeInsets.only(top: 5, bottom: 5),
        child: _bulidSegemtItem(list[i], i),
      );
      items.add(item);
    }

    return items;
  }

  ///创建item position 是item的位置,根据位置 设置不同 的属性
  _bulidSegemtItem(String name, int position) {
    return Container(
      //有边框的时候按钮高度减去边框宽度 保持按钮高度选中不选中一样
      height: selectItem == position
          ? widget.itemHeight
          : widget.itemHeight - widget.borderWidth,
      width: widget.itemWidth,
      //如果 当前item 是选中的item 则创建 flatButton 如果不是 则创建 带边框属行的 outlineButton
      child: selectItem == position
          ? FlatButton(
              //判断 当前item 的位置,第一个 左上角和左下角 带圆角 如果是最后一个 右上角和右下角带圆角,其他按钮不带圆角
              shape: position == 0
                  ? RoundedRectangleBorder(
                      borderRadius: BorderRadius.only(
                          topLeft: Radius.circular(widget.radius),
                          bottomLeft: Radius.circular(widget.radius)))
                  : position == widget.titleNames.length - 1
                      ? RoundedRectangleBorder(
                          borderRadius: BorderRadius.only(
                              topRight: Radius.circular(widget.radius),
                              bottomRight: Radius.circular(widget.radius)))
                      : RoundedRectangleBorder(),
              color: selectItem == position
                  ? widget.selectedColor
                  : widget.defaultColor,
              onPressed: () {
                _updateItem(position);
              },
              child: Text(
                name,
                style: TextStyle(
                  fontSize: widget.textSize,
                  color: selectItem == position
                      ? widget.defaultColor
                      : widget.selectedColor,
                ),
              ),
            )
          : OutlineButton(
              shape: position == 0
                  ? RoundedRectangleBorder(
                      borderRadius: BorderRadius.only(
                          topLeft: Radius.circular(widget.radius),
                          bottomLeft: Radius.circular(widget.radius)))
                  : position == widget.titleNames.length - 1
                      ? RoundedRectangleBorder(
                          borderRadius: BorderRadius.only(
                              topRight: Radius.circular(widget.radius),
                              bottomRight: Radius.circular(widget.radius)))
                      : RoundedRectangleBorder(),
              borderSide: BorderSide(
                  color: widget.selectedColor, width: widget.borderWidth),
              color: selectItem == position
                  ? widget.selectedColor
                  : widget.defaultColor,
              //点击时候 的边框颜色
              highlightedBorderColor: widget.selectedColor,
              onPressed: () {
                _updateItem(position);
              },
              child: Text(
                name,
                style: TextStyle(
                  fontSize: widget.textSize,
                  color: selectItem == position
                      ? widget.defaultColor
                      : widget.selectedColor,
                ),
              ),
            ),
    );
  }

  //点击修改视图样式,回调点击的方法
  _updateItem(int selectedPosition) {
    if (selectedPosition == selectItem) {
      return;
    } else {
      selectItem = selectedPosition;
      widget.onSelectChanged(selectedPosition);
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: _buildSegmentItems(widget.titleNames),
    );
  }
}

 

调用方式:


List<String> titleNames = ["年", "月", "周"];

SegmentBar(
                  titleNames: titleNames,
                  onSelectChanged: (position) {
                    print("Sagment" + position.toString());
                  })

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值