You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现点击按钮按周增减日期并显示周起止日期

Flutter 实现按周增减的日期选择器

问题修正与优化说明

现有代码的核心需求是实现点击按钮切换上周/下周,并显示对应周的起止日期,但存在几个关键问题:

  • 初始日期未定位到当前周的第一天,而是直接使用当天,导致初始显示的不是完整自然周
  • addWeekly函数手动修改日期的day值,会出现跨月/跨年时的日期错误(比如2月3日减7天会生成无效日期)
  • 周起始日逻辑不明确,无法保证显示的是标准自然周

修正后的完整代码

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class DateCounter extends StatefulWidget {
  const DateCounter({Key? key}) : super(key: key);

  @override
  State<DateCounter> createState() => _DateCounterState();
}

class _DateCounterState extends State<DateCounter> {
  final _dateFormat = DateFormat('dd-MM-yyyy');
  late DateTime _currentWeekStart;
  late String _weekStartText;
  late String _weekEndText;

  // 定义周起始日:1=周一,7=周日,可按需修改
  static const int _weekStartDay = 1;

  @override
  void initState() {
    super.initState();
    // 初始化时获取当前周的第一天
    _currentWeekStart = _getCurrentWeekStart();
    _updateWeekDisplayText();
  }

  // 计算当前周的起始日期
  DateTime _getCurrentWeekStart() {
    final now = DateTime.now();
    // 算出当前日期与周起始日的差值,校准到周第一天
    final daysToSubtract = (now.weekday - _weekStartDay + 7) % 7;
    return DateTime(now.year, now.month, now.day - daysToSubtract);
  }

  // 更新周起止日期的显示文本
  void _updateWeekDisplayText() {
    final weekEnd = _currentWeekStart.add(const Duration(days: 6));
    _weekStartText = _dateFormat.format(_currentWeekStart);
    _weekEndText = _dateFormat.format(weekEnd);
  }

  // 切换到上周
  void _switchToPreviousWeek() {
    setState(() {
      _currentWeekStart = _currentWeekStart.subtract(const Duration(days: 7));
      _updateWeekDisplayText();
    });
  }

  // 切换到下周
  void _switchToNextWeek() {
    setState(() {
      _currentWeekStart = _currentWeekStart.add(const Duration(days: 7));
      _updateWeekDisplayText();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 减号按钮
            IconButton(
              onPressed: _switchToPreviousWeek,
              icon: const Icon(Icons.remove_circle),
              iconSize: 30,
              color: Colors.grey,
            ),
            // 日期显示区域
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20),
              child: Text(
                "$_weekStartText 至 $_weekEndText",
                style: const TextStyle(fontSize: 16),
              ),
            ),
            // 加号按钮
            IconButton(
              onPressed: _switchToNextWeek,
              icon: const Icon(Icons.add_circle),
              iconSize: 30,
              color: Colors.grey,
            ),
          ],
        ),
      ),
    );
  }
}

核心改进点

  • 周起始校准:通过_getCurrentWeekStart函数精准计算当前周的第一天,确保初始显示完整自然周
  • 安全日期计算:使用add/subtract结合Duration处理周切换,自动适配跨月、跨年场景,避免手动修改日期导致的错误
  • 代码简化:将日期文本更新逻辑统一到_updateWeekDisplayText,减少重复代码
  • UI优化:使用Flutter原生IconButton替代自定义容器,交互体验更规范

自定义调整

如果需要将周起始日改为周日,仅需修改常量值:

static const int _weekStartDay = 7;

内容的提问来源于stack exchange,提问作者Rajesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:35:26