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

如何在Flutter中实现范围日期选择器(无需使用Syncfusion包)

Flutter实现范围日期选择器(非Syncfusion方案)

以下是几种无需付费Syncfusion包的实现方案,覆盖基础需求到高度定制场景:

一、使用Flutter官方自带组件showDateRangePicker

这是最便捷的方案,无需额外依赖,完全免费且支持基础样式定制。

代码示例:

Future<void> _openRangePicker(BuildContext context) async {
  final DateTimeRange? pickedRange = await showDateRangePicker(
    context: context,
    firstDate: DateTime(2020),
    lastDate: DateTime(2030),
    // 设置初始选中范围
    initialDateRange: DateTimeRange(
      start: DateTime.now(),
      end: DateTime.now().add(const Duration(days: 7)),
    ),
    // 自定义主题样式
    builder: (context, child) {
      return Theme(
        data: ThemeData.light().copyWith(
          colorScheme: const ColorScheme.light(
            primary: Colors.blueAccent, // 选中日期的主色
            onPrimary: Colors.white,
            surface: Colors.grey[100]!,
          ),
          dialogBackgroundColor: Colors.white,
        ),
        child: child!,
      );
    },
  );

  if (pickedRange != null) {
    // 处理选中的日期范围
    print('选中范围:${pickedRange.start} 至 ${pickedRange.end}');
  }
}

二、使用免费第三方包flutter_date_pickers

该包采用MIT许可,支持范围、单个、多个日期选择,样式定制更灵活。

步骤1:添加依赖

在pubspec.yaml中加入:

dependencies:
  flutter_date_pickers: ^2.0.0 # 请使用最新版本

代码示例:

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

class RangePickerPage extends StatefulWidget {
  const RangePickerPage({super.key});

  @override
  State<RangePickerPage> createState() => _RangePickerPageState();
}

class _RangePickerPageState extends State<RangePickerPage> {
  DateTimeRange _selectedRange = DateTimeRange(
    start: DateTime.now(),
    end: DateTime.now().add(const Duration(days: 3)),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('范围日期选择器')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: RangePicker(
          selectedDateRange: _selectedRange,
          onChanged: (newRange) => setState(() => _selectedRange = newRange),
          firstDate: DateTime(2020),
          lastDate: DateTime(2030),
          datePickerStyles: DatePickerStyles(
            selectedDateStyle: const TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.bold,
            ),
            selectedSingleDateDecoration: BoxDecoration(
              color: Colors.blueAccent,
              borderRadius: BorderRadius.circular(8),
            ),
            rangeMiddleDecoration: BoxDecoration(
              color: Colors.blueAccent.withOpacity(0.2),
            ),
          ),
        ),
      ),
    );
  }
}

三、基于TableCalendar自定义高度定制的选择器

如果需要完全控制UI细节(比如范围边框、渐变背景),可以使用MIT许可的TableCalendar包实现。

步骤1:添加依赖

dependencies:
  table_calendar: ^3.0.0 # 请使用最新版本

代码示例:

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

class CustomRangePicker extends StatefulWidget {
  const CustomRangePicker({super.key});

  @override
  State<CustomRangePicker> createState() => _CustomRangePickerState();
}

class _CustomRangePickerState extends State<CustomRangePicker> {
  DateTime? _focusedDay;
  DateTime? _rangeStart;
  DateTime? _rangeEnd;

  @override
  void initState() {
    super.initState();
    _focusedDay = DateTime.now();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('自定义范围日期选择')),
      body: TableCalendar(
        firstDay: DateTime(2020),
        lastDay: DateTime(2030),
        focusedDay: _focusedDay!,
        rangeStartDay: _rangeStart,
        rangeEndDay: _rangeEnd,
        calendarFormat: CalendarFormat.month,
        onRangeSelected: (start, end, focusedDay) {
          setState(() {
            _rangeStart = start;
            _rangeEnd = end;
            _focusedDay = focusedDay;
          });
        },
        selectedDayPredicate: (day) => 
            isSameDay(_rangeStart, day) || isSameDay(_rangeEnd, day),
        // 自定义范围样式
        rangeStartDecoration: const BoxDecoration(
          color: Colors.blueAccent,
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(12),
            bottomLeft: Radius.circular(12),
          ),
        ),
        rangeEndDecoration: const BoxDecoration(
          color: Colors.blueAccent,
          borderRadius: BorderRadius.only(
            topRight: Radius.circular(12),
            bottomRight: Radius.circular(12),
          ),
        ),
        rangeMiddleDecoration: BoxDecoration(
          color: Colors.blueAccent.withOpacity(0.3),
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:00:31