flutter 实现一个月份切换的控件

本文介绍了一个基于Flutter的水平月份选择器组件的实现细节。该组件允许用户在给定的时间范围内选择日期,通过左右箭头图标进行月份切换,并提供自定义图标和回调函数。文章详细展示了如何使用状态管理和日期解析来构建此控件。
摘要由CSDN通过智能技术生成

效果如上图

完整代码

class HorizontalMonthPicker extends BaseWidget {
  DateTime startTime;
  DateTime endTime;
  DateTime selectedTime;
  String leftSelectableIcon;
  String rightSelectableIcon;
  String leftUnselectableIcon;
  String rightUnselectableIcon;
  Function onChange;
  HorizontalMonthPicker(
      this.startTime,
      this.endTime,
      this.selectedTime,
      this.leftSelectableIcon,
      this.rightSelectableIcon,
      this.leftUnselectableIcon,
      this.rightUnselectableIcon,
      this.onChange);
  @override
  State<HorizontalMonthPicker> createState() => HorizontalMonthPickerState();
}

class HorizontalMonthPickerState
    extends BaseWidgetState<HorizontalMonthPicker> {
  DateTime selectedTime;
  DateTime startTime;
  DateTime endTime;
  int selectedYear;
  int selectedMonth;
  int selectedDay = 01;
  String day = '-01';
  @override
  void initState() {
    super.initState();
    DateTime dateTime = DateTime.parse("2018-01-01");
    print("${dateTime.year}");
    print("${dateTime.month}");
    print("${dateTime.day}");
    selectedTime = rebuildTime2Month(widget.selectedTime);
    startTime = rebuildTime2Month(widget.startTime);
    endTime = rebuildTime2Month(widget.endTime);
    selectedYear = widget.selectedTime.year;
    selectedMonth = widget.selectedTime.month;
    selectedDay = widget.selectedTime.day;
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Container(
        color: Colors.red,
        height: 40,
        child: Row(
          children: <Widget>[
            InkWell(
              child: Image.asset(
                selectedTime.isAfter(startTime)
                    ? widget.leftSelectableIcon
                    : widget.leftUnselectableIcon,
                width: 9,
                height: 16,
              ),
              onTap: () {
                if (parseTime(selectedYear, selectedMonth, selectedDay)
                    .isAfter(startTime)) {
                  minusTime();
                  widget.onChange(selectedTime);
                }
              },
            ),
            SizedBox(
              width: 38,
            ),
            Text("${selectedTime.year}-${selectedTime.month}"),
            SizedBox(
              width: 38,
            ),
            InkWell(
              child: Image.asset(
                selectedTime.isBefore(endTime)
                    ? widget.rightSelectableIcon
                    : widget.rightUnselectableIcon,
                width: 9,
                height: 16,
              ),
              onTap: () {
                if (parseTime(selectedYear, selectedMonth, selectedDay)
                    .isBefore(endTime)) {
                  plusTime();
                  widget.onChange(selectedTime);
               }
              },
            ),
          ],
        ),
      ),
    );
  }

  DateTime parseTime(int year, int month, int day) {
    if (month < 10) {
      return DateTime.parse("${year}-0${month}-01");
    } else {
      return DateTime.parse("${year}-${month}-01");
    }
  }

  void minusTime() {
    selectedMonth--;
    if (selectedMonth == 0) {
      selectedYear--;
      selectedMonth = 12;
    }
    selectedTime = parseTime(selectedYear, selectedMonth, selectedDay);
    setState(() {});
  }

  void plusTime() {
    selectedMonth++;
    if (selectedMonth == 13) {
      this.selectedYear++;
      this.selectedMonth = 1;
    }
    selectedTime = parseTime(selectedYear, selectedMonth, selectedDay);
    setState(() {});
  }

   
  //抹除掉日期带来的影响,否则可能切换到范围之外
  DateTime rebuildTime2Month(DateTime dateTime) {
    int month = dateTime.month;
    String monthS = '';
    if (month < 10) {
      monthS = "-0${month}";
    } else {
      monthS = "-${month}";
    }
    return DateTime.parse("${dateTime.year}${monthS}${day}");
  }
}

basewidget是自己封装的基础组件,不过这个控件的实现没有用到其中的代码,所以没有关系

调用方法:

HorizontalMonthPicker(
          DateTime.parse("2018-01-01"),
          DateTime.parse("2019-06-06"),
          DateTime.parse("2019-06-01"),
          "assets/leftselect.png",
          "assets/rightselect.png",
          "assets/leftnotselect.png",
          "assets/rightunselect.png", (DateTime v) {
        print("${v.year}");
      })

参数较多,容易传错,b careful

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值