Flutter如何设置DateTimeRange中的最大日期范围持续时间

huangapple go评论73阅读模式
英文:

Flutter How to set the maximum date range duration in DateTimeRange

问题

以下是您提供的代码的翻译部分:

我有以下的代码,使用了一个`DateTimeRange`,我想允许用户选择不超过15天的时间范围。例如,今天之前的时间范围将是02/0202/16或更早,今天之后的时间范围将是02/1403/01或更晚。如果可能的话,我该如何做?

class DateRangeView extends StatefulWidget {
  late bool isClearClicked;

  DateRangeView({Key? key, required this.isClearClicked}) : super(key: key);

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

class DateRangeViewState extends State<DateRangeView> {
  DateTimeRange? dateRange;
  DateTimeRange? initialDateRange;
  DateTimeRange? newDateRange;

  String getFrom() {
    if (dateRange == null) {
      return DateTime.now().toRangeDate();
    } else {
      return dateRange!.start.toRangeDate();
    }
  }

  String getUntil() {
    if (dateRange == null) {
      return DateTime.now().toRangeDate();
    } else {
      return dateRange!.end.toRangeDate();
    }
  }

  @override
  Widget build(BuildContext context) {
    return HeaderWidget(
      title: Translation.current.period.toUpperCase(),
      child: Row(
        children: [
          Expanded(
            child: ButtonWidget(
              text: widget.isClearClicked
                  ? DateTime.now().toRangeDate()
                  : getFrom(),
              onClicked: () => pickDateRange(context),
            ),
          ),
          Text(Translation.current.untilDateKeyword.toUpperCase(),
            style:
            TextStyle(fontSize: ThemeSize.text(xl), color: ThemeColor.gray500),
          ),
          Expanded(
            child: ButtonWidget(
              text: widget.isClearClicked
                  ? DateTime.now().toRangeDate()
                  : getUntil(),
              onClicked: () => pickDateRange(context),
            ),
          ),
          Icon( Icons.calendar_month_rounded, color: ThemeColor.gray600,),
        ],
      ),
    );
  }

  Future pickDateRange(BuildContext context) async {
      initialDateRange = DateTimeRange(
      start: DateTime.now(),
      end: DateTime.now(),
    );
    newDateRange = await showDateRangePicker(
      initialEntryMode: DatePickerEntryMode.calendarOnly,
      context: context,
      firstDate: DateTime(2022),
      lastDate: DateTime(2030),
      initialDateRange: dateRange ?? initialDateRange,
        builder: (context, Widget? child) => Theme(
          data:ThemeData.light().copyWith(
            //Header background color
            primaryColor: ThemeColor.primaryVariant,
            scaffoldBackgroundColor: Colors.grey[50],
            dividerColor: Colors.grey,
            textTheme: TextTheme(
              bodyText2:
              TextStyle(color: ThemeColor.gray700, fontSize: ThemeSize.text(xxl)),
            ),
            colorScheme: ColorScheme.fromSwatch().copyWith(
              primary: ThemeColor.primaryVariant,
              onSurface: Colors.black,
            ),
          ),
          child: child!,
        ),
    );

    if (newDateRange == null) return;

    setDateRange();
  }

  setDateRange() {
    setState(() {
      dateRange = newDateRange;
      widget.isClearClicked = false;
    });
    Future.delayed(
      const Duration(milliseconds: 100), () {
        dateRange = initialDateRange;
        },
    );
  }
}

请注意,代码中可能存在一些自定义函数和类(如HeaderWidgetButtonWidgetTranslationThemeSizeThemeColor等),这些部分的翻译可能需要根据您的实际代码进行调整。

英文:

I have the following code with a DateTimeRange and I would like to allow the user to select a range without exceed 15 days. For example a range before today will be 02/02 to 02/16 or lower or after today 02/14 to 03/01 or lower. How can I do that if it's possible ?

class DateRangeView extends StatefulWidget {
late bool isClearClicked;
DateRangeView({Key? key, required this.isClearClicked}) : super(key: key);
@override
DateRangeView createState() =&gt; DateRangeViewState();
}
class DateRangeViewState extends State&lt;DateRangeView&gt; {
DateTimeRange? dateRange;
DateTimeRange? initialDateRange;
DateTimeRange? newDateRange;
String getFrom() {
if (dateRange == null) {
return DateTime.now().toRangeDate();
} else {
return dateRange!.start.toRangeDate();
}
}
String getUntil() {
if (dateRange == null) {
return DateTime.now().toRangeDate();
} else {
return dateRange!.end.toRangeDate();
}
}
@override
Widget build(BuildContext context) {
return HeaderWidget(
title: Translation.current.period.toUpperCase(),
child: Row(
children: [
Expanded(
child: ButtonWidget(
text: widget.isClearClicked
? DateTime.now().toRangeDate()
: getFrom(),
onClicked: () =&gt; pickDateRange(context),
),
),
Text(Translation.current.untilDateKeyword.toUpperCase(),
style:
TextStyle(fontSize: ThemeSize.text(xl), color: ThemeColor.gray500),
),
Expanded(
child: ButtonWidget(
text: widget.isClearClicked
? DateTime.now().toRangeDate()
: getUntil(),
onClicked: () =&gt; pickDateRange(context),
),
),
Icon( Icons.calendar_month_rounded, color: ThemeColor.gray600,),
],
),
);
}
Future pickDateRange(BuildContext context) async {
initialDateRange = DateTimeRange(
start: DateTime.now(),
end: DateTime.now(),
);
newDateRange = await showDateRangePicker(
initialEntryMode: DatePickerEntryMode.calendarOnly,
context: context,
firstDate: DateTime(2022),
lastDate: DateTime(2030),
initialDateRange: dateRange ?? initialDateRange,
builder: (context, Widget? child) =&gt; Theme(
data:ThemeData.light().copyWith(
//Header background color
primaryColor: ThemeColor.primaryVariant,
scaffoldBackgroundColor: Colors.grey[50],
dividerColor: Colors.grey,
textTheme: TextTheme(
bodyText2:
TextStyle(color: ThemeColor.gray700, fontSize: ThemeSize.text(xxl)),
),
colorScheme: ColorScheme.fromSwatch().copyWith(
primary: ThemeColor.primaryVariant,
onSurface: Colors.black,
),
),
child: child!,
),
);
if (newDateRange == null) return;
setDateRange();
}
setDateRange() {
setState(() {
dateRange = newDateRange;
widget.isClearClicked = false;
});
Future.delayed(
const Duration(milliseconds: 100), () {
dateRange = initialDateRange;
},
);
}
}

答案1

得分: 1

你可以使用syncfusion_flutter_datepicker库。它具有一个selectionChanged回调,您可以操作以动态限制可选择的日期。这是我对类似问题的答案

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

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final DateTime _minDate = DateTime.now();
  DateTime _maxDate = DateTime.now().add(const Duration(days: 365));

  final Duration _duration = const Duration(days: 14);

  DateTime _start = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: SfDateRangePicker(
        minDate: _minDate,
        maxDate: _maxDate,
        selectionMode: DateRangePickerSelectionMode.range,
        onSelectionChanged: (DateRangePickerSelectionChangedArgs args) {
          if (args.value is PickerDateRange) {
            _start = (args.value as PickerDateRange).startDate!;
            setState(() {
              // 限制最大日期为从选定日期开始的14天
              _maxDate = _start.add(_duration);
            });
          }
        },
      )),
    );
  }
}
英文:

You can use syncfusion_flutter_datepicker library. It has a selectionChanged callback that you can manipulate to limit selectable dates on the go. This is my answer to a similar question

class Home extends StatefulWidget {
const Home({super.key});
@override
State&lt;Home&gt; createState() =&gt; _HomeState();
}
class _HomeState extends State&lt;Home&gt; {
final DateTime _minDate = DateTime.now();
DateTime _maxDate = DateTime.now().add(const Duration(days: 365));
final Duration _duration = const Duration(days: 14);
DateTime _start = DateTime.now();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SfDateRangePicker(
minDate: _minDate,
maxDate: _maxDate,
selectionMode: DateRangePickerSelectionMode.range,
onSelectionChanged: (DateRangePickerSelectionChangedArgs args) {
if (args.value is PickerDateRange) {
_start = (args.value as PickerDateRange).startDate!;
setState(() {
// limit the maxDate to 14 days from selected date
_maxDate = _start.add(_duration);
});
}
},
)),
);
}
}

答案2

得分: 0

你可以将这两个参数更改为:

firstDate: DateTime.now(),
lastDate: DateTime.now().add(Duration(days: 15)),
英文:

You can change this two params to :

firstDate: DateTime.now(),
lastDate: DateTime.now().add(Duration(days: 15)),

huangapple
  • 本文由 发表于 2023年2月14日 06:58:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75441968.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定