import 'dart:math' as math; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; // layout defaults const Duration _kPageScrollDuration = Duration(milliseconds: 200); const double _kDayPickerRowHeight = 42.0; const int _kMaxDayPickerRowCount = 6; // A 31 day month that starts on Saturday. const double _kMonthPickerPortraitWidth = 330.0; const EdgeInsetsGeometry _kContentPadding = EdgeInsets.symmetric(horizontal: 8.0); /// Settings for the layout of the [DayPicker], [WeekPicker], [RangePicker] /// and [MonthPicker]. class DatePickerLayoutSettings { /// Duration for scroll to previous or next page. final Duration pagesScrollDuration; /// Determines the scroll physics of a date picker widget. /// /// Can be null. In this case default physics for [ScrollView] will be used. final ScrollPhysics? scrollPhysics; /// Height of the one row in picker including headers. /// /// Default is [_kDayPickerRowHeight]. final double dayPickerRowHeight; /// Width of the day based pickers. final double monthPickerPortraitWidth; /// Width of the day based pickers. final double yearPickerPortraitWidth; /// final int maxDayPickerRowCount; /// Padding for the entire picker. final EdgeInsetsGeometry contentPadding; /// If the first dates from the next month should be shown /// to complete last week of the selected month. /// /// false by default. final bool showNextMonthStart; /// If the last dates from the previous month should be shown /// to complete first week of the selected month. /// /// false by default. final bool showPrevMonthEnd; /// Hide Month navigation row /// false by default. final bool hideMonthNavigationRow; /// Grid delegate for the picker according to [dayPickerRowHeight] and /// [maxDayPickerRowCount]. SliverGridDelegate get dayPickerGridDelegate => _DayPickerGridDelegate(dayPickerRowHeight, maxDayPickerRowCount); /// Maximum height of the day based picker according to [dayPickerRowHeight] /// and [maxDayPickerRowCount]. /// /// Two extra rows: /// one for the day-of-week header and one for the month header. double get maxDayPickerHeight => dayPickerRowHeight * (maxDayPickerRowCount + 2); /// Creates layout settings for the date picker. /// /// Usually used in [DayPicker], [WeekPicker], [RangePicker] /// and [MonthPicker]. const DatePickerLayoutSettings({ this.pagesScrollDuration = _kPageScrollDuration, this.dayPickerRowHeight = _kDayPickerRowHeight, this.monthPickerPortraitWidth = _kMonthPickerPortraitWidth, this.yearPickerPortraitWidth = _kMonthPickerPortraitWidth, this.maxDayPickerRowCount = _kMaxDayPickerRowCount, this.contentPadding = _kContentPadding, this.showNextMonthStart = false, this.showPrevMonthEnd = false, this.hideMonthNavigationRow = false, this.scrollPhysics, }); } class _DayPickerGridDelegate extends SliverGridDelegate { final double _dayPickerRowHeight; final int _maxDayPickerRowCount; const _DayPickerGridDelegate( this._dayPickerRowHeight, this._maxDayPickerRowCount); @override SliverGridLayout getLayout(SliverConstraints constraints) { const int columnCount = DateTime.daysPerWeek; final double tileWidth = constraints.crossAxisExtent / columnCount; final double tileHeight = math.min(_dayPickerRowHeight, constraints.viewportMainAxisExtent / (_maxDayPickerRowCount + 1)); return SliverGridRegularTileLayout( crossAxisCount: columnCount, mainAxisStride: tileHeight, crossAxisStride: tileWidth, childMainAxisExtent: tileHeight, childCrossAxisExtent: tileWidth, reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection), ); } @override bool shouldRelayout(SliverGridDelegate oldDelegate) => false; }