/// <summary> /// Initializes the specified minimum date. /// </summary> /// <param name="minDate">The minimum date.</param> /// <param name="maxDate">The maximum date.</param> /// <param name="highlightedDaysOfWeek">The highlighted days of week.</param> /// <returns>FluentInitializer.</returns> /// <exception cref="Java.Lang.IllegalArgumentException"> /// minDate and maxDate must be non-zero. + /// Debug(minDate, maxDate) /// or /// minDate must be before maxDate. + /// Debug(minDate, maxDate) /// </exception> public EFluentInitializer Init(DateTime minDate, DateTime maxDate, DayOfWeek[] highlightedDaysOfWeek) { if (minDate == DateTime.MinValue || maxDate == DateTime.MinValue) { throw new IllegalArgumentException("minDate and maxDate must be non-zero. " + Debug(minDate, maxDate)); } if (minDate.CompareTo(maxDate) > 0) { throw new IllegalArgumentException("minDate must be before maxDate. " + Debug(minDate, maxDate)); } HighlighDaysOfWeeks(highlightedDaysOfWeek); Mode = SelectionMode.Single; //Clear out any previously selected dates/cells. SelectedCals.Clear(); SelectedCells.Clear(); _highlightedCals.Clear(); _highlightedCells.Clear(); //Clear previous state. Cells.Clear(); Months.Clear(); MinDate = minDate; MaxDate = maxDate; MinDate = SetMidnight(MinDate); MaxDate = SetMidnight(MaxDate); // maxDate is exclusive: bump back to the previous day so if maxDate is the first of a month, // We don't accidentally include that month in the view. if (MaxDate.Day == 1) { MaxDate = MaxDate.AddMinutes(-1); } //Now iterate between minCal and maxCal and build up our list of months to show. _monthCounter = MinDate; int maxMonth = MaxDate.Month; int maxYear = MaxDate.Year; while ((_monthCounter.Month <= maxMonth || _monthCounter.Year < maxYear) && _monthCounter.Year < maxYear + 1) { var month = new MonthDescriptor(_monthCounter.Month, _monthCounter.Year, _monthCounter, _monthCounter.ToString(MonthNameFormat), _styleDescriptor); Cells.Add(GetMonthCells(month, _monthCounter)); Logr.D("Adding month {0}", month); Months.Add(month); _monthCounter = _monthCounter.AddMonths(1); } ValidateAndUpdate(); return(new EFluentInitializer(this)); }
/// <summary> /// Called when [measure]. /// </summary> /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent. /// The requirements are encoded with /// <c><see cref="T:Android.Views.View+MeasureSpec" /></c>.</param> /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent. /// The requirements are encoded with /// <c><see cref="T:Android.Views.View+MeasureSpec" /></c>.</param> /// <exception cref="System.InvalidOperationException">Must have at least one month to display. Did you forget to call Init()?</exception> /// <since version="Added in API level 1" /> /// <altmember cref="P:Android.Views.View.MeasuredWidth" /> /// <altmember cref="P:Android.Views.View.MeasuredHeight" /> /// <altmember cref="M:Android.Views.View.SetMeasuredDimension(System.Int32, System.Int32)" /> /// <altmember cref="M:Android.Views.View.get_SuggestedMinimumHeight" /> /// <altmember cref="M:Android.Views.View.get_SuggestedMinimumWidth" /> /// <altmember cref="M:Android.Views.View.MeasureSpec.GetMode(System.Int32)" /> /// <altmember cref="M:Android.Views.View.MeasureSpec.GetSize(System.Int32)" /> /// <remarks><para tool="javadoc-to-mdoc" /> /// <para tool="javadoc-to-mdoc"> /// Measure the view and its content to determine the measured width and the /// measured height. This method is invoked by <c><see cref="M:Android.Views.View.Measure(System.Int32, System.Int32)" /></c> and /// should be overriden by subclasses to provide accurate and efficient /// measurement of their contents. /// </para> /// <para tool="javadoc-to-mdoc"> /// <i>CONTRACT:</i> When overriding this method, you /// <i>must</i> call <c><see cref="M:Android.Views.View.SetMeasuredDimension(System.Int32, System.Int32)" /></c> to store the /// measured width and height of this view. Failure to do so will trigger an /// <c>IllegalStateException</c>, thrown by /// <c><see cref="M:Android.Views.View.Measure(System.Int32, System.Int32)" /></c>. Calling the superclass' /// <c><see cref="M:Android.Views.View.OnMeasure(System.Int32, System.Int32)" /></c> is a valid use. /// </para> /// <para tool="javadoc-to-mdoc"> /// The base class implementation of measure defaults to the background size, /// unless a larger size is allowed by the MeasureSpec. Subclasses should /// override <c><see cref="M:Android.Views.View.OnMeasure(System.Int32, System.Int32)" /></c> to provide better measurements of /// their content. /// </para> /// <para tool="javadoc-to-mdoc"> /// If this method is overridden, it is the subclass's responsibility to make /// sure the measured height and width are at least the view's minimum height /// and width (<c><see cref="M:Android.Views.View.get_SuggestedMinimumHeight" /></c> and /// <c><see cref="M:Android.Views.View.get_SuggestedMinimumWidth" /></c>). /// </para> /// <para tool="javadoc-to-mdoc"> /// <format type="text/html"> /// <a href="http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)" target="_blank">[Android Documentation]</a> /// </format> /// </para></remarks> protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (Months.Count == 0) { throw new InvalidOperationException( "Must have at least one month to display. Did you forget to call Init()?"); } Logr.D("PickerView.OnMeasure w={0} h={1}", MeasureSpec.ToString(widthMeasureSpec), MeasureSpec.ToString(heightMeasureSpec)); base.OnMeasure(widthMeasureSpec, heightMeasureSpec); }
/// <summary> /// Gets the month cells. /// </summary> /// <param name="month">The month.</param> /// <param name="startCal">The start cal.</param> /// <returns>List<List<MonthCellDescriptor>>.</returns> internal List <List <MonthCellDescriptor> > GetMonthCells(MonthDescriptor month, DateTime startCal) { var cells = new List <List <MonthCellDescriptor> >(); var cal = new DateTime(startCal.Year, startCal.Month, 1); var firstDayOfWeek = (int)cal.DayOfWeek; cal = cal.AddDays((int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - firstDayOfWeek); var minSelectedCal = GetMinDate(SelectedCals); var maxSelectedCal = GetMaxDate(SelectedCals); while ((cal.Month < month.Month + 1 || cal.Year < month.Year) && cal.Year <= month.Year) { Logr.D("Building week row starting at {0}", cal); var weekCells = new List <MonthCellDescriptor>(); cells.Add(weekCells); for (int i = 0; i < 7; i++) { var date = cal; bool isCurrentMonth = cal.Month == month.Month; bool isSelected = isCurrentMonth && ContatinsDate(SelectedCals, cal); bool isSelectable = isCurrentMonth && IsBetweenDates(cal, MinDate, MaxDate); bool isToday = IsSameDate(cal, Today); bool isHighlighted = ContatinsDate(_highlightedCals, cal) || _hlighlightedDaysOfWeek[(int)cal.DayOfWeek]; int value = cal.Day; var rangeState = RangeState.None; if (SelectedCals.Count > 1) { if (IsSameDate(minSelectedCal, cal)) { rangeState = RangeState.First; } else if (IsSameDate(maxSelectedCal, cal)) { rangeState = RangeState.Last; } else if (IsBetweenDates(cal, minSelectedCal, maxSelectedCal)) { rangeState = RangeState.Middle; } } weekCells.Add(new MonthCellDescriptor(date, isCurrentMonth, isSelectable, isSelected, isToday, isHighlighted, value, rangeState, _styleDescriptor)); cal = cal.AddDays(1); } } return(cells); }
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.calendar_picker); var nextYear = DateTime.Now.AddYears(1); var calendar = FindViewById <CalendarPickerView>(Resource.Id.calendar_view); calendar.Init(DateTime.Now, nextYear) .InMode(CalendarPickerView.SelectionMode.Single) .WithSelectedDate(DateTime.Now) .WithHighlightedDate(DateTime.Now.AddDays(2)); calendar.OnDateSelected += (s, e) => Toast.MakeText(this, e.SelectedDate.ToShortDateString(), ToastLength.Short).Show(); var btnSingle = FindViewById <Button>(Resource.Id.button_single); var btnMulti = FindViewById <Button>(Resource.Id.button_multi); var btnRange = FindViewById <Button>(Resource.Id.button_range); var btnDialog = FindViewById <Button>(Resource.Id.button_dialog); btnSingle.Click += (s, e) => { btnSingle.Enabled = false; btnMulti.Enabled = true; btnRange.Enabled = true; calendar.Init(DateTime.Now, nextYear) .InMode(CalendarPickerView.SelectionMode.Single) .WithSelectedDate(DateTime.Now); }; btnMulti.Click += (s, e) => { btnSingle.Enabled = true; btnMulti.Enabled = false; btnRange.Enabled = true; var dates = new List <DateTime>(); for (int i = 0; i < 5; i++) { dates.Add(DateTime.Now.AddDays(3 * i)); } calendar.Init(DateTime.Now, nextYear) .InMode(CalendarPickerView.SelectionMode.Multi) .WithSelectedDates(dates); }; btnRange.Click += (s, e) => { btnSingle.Enabled = true; btnMulti.Enabled = true; btnRange.Enabled = false; var dates = new List <DateTime>() { DateTime.Now.AddDays(3), DateTime.Now.AddDays(5) }; calendar.Init(DateTime.Now, nextYear) .InMode(CalendarPickerView.SelectionMode.Range) .WithSelectedDates(dates); }; btnDialog.Click += (s, e) => { var dialogView = (CalendarPickerView)LayoutInflater.Inflate(Resource.Layout.dialog, null, false); dialogView.Init(DateTime.Now, nextYear); new AlertDialog.Builder(this).SetTitle("I'm a dialog!") .SetView(dialogView) .SetNeutralButton("Dismiss", (sender, args) => { }).Create().Show(); }; FindViewById <Button>(Resource.Id.done_button).Click += (s, o) => { calendar = FindViewById <CalendarPickerView>(Resource.Id.calendar_view); Logr.D(TAG, "Selected time in millis: " + calendar.SelectedDate); string toast = "Selected: " + calendar.SelectedDate; Toast.MakeText(this, toast, ToastLength.Short).Show(); }; }