Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue18797.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue18797"
xmlns:ns="clr-namespace:Maui.Controls.Sample.Issues">
<VerticalStackLayout>
<DatePicker Focused="DatePicker_Focused" Unfocused="DatePicker_Unfocused" AutomationId="datePicker"/>
<Label x:Name="FocusedLabel" AutomationId="focusedLabel" Text="Focused: false"/>
<Label x:Name="UnfocusedLabel" AutomationId="unfocusedLabel" Text="Unfocused: false"/>
</VerticalStackLayout>
</ContentPage>
22 changes: 22 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue18797.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Maui.Controls.Sample.Issues
{
[XamlCompilation(XamlCompilationOptions.Compile)]
[Issue(IssueTracker.Github, 18797, "[Android] Datepicker focus and unfocus event not firing on android", PlatformAffected.Android)]
public partial class Issue18797 : ContentPage
{
public Issue18797()
{
InitializeComponent();
}

void DatePicker_Focused(object sender, FocusEventArgs e)
{
FocusedLabel.Text = "Focused: true";
}

void DatePicker_Unfocused(object sender, FocusEventArgs e)
{
UnfocusedLabel.Text = "Unfocused: true";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#if ANDROID
using NUnit.Framework;
using NUnit.Framework.Legacy;
using OpenQA.Selenium.Appium;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues
{
public class Issue18797 : _IssuesUITest
{
public override string Issue => "[Android] Datepicker focus and unfocus event not firing on android";

public Issue18797(TestDevice device) : base(device)
{
}

[Test]
[Category(UITestCategories.DatePicker)]
public void DatePickerFocusedAndUnfocusedEventsShouldFire()
{
_ = App.WaitForElement("datePicker");

App.Click("datePicker");
App.WaitForElement("Cancel");
App.Click("Cancel");
App.WaitForElement("focusedLabel");
var focusedLabelText = App.FindElement("focusedLabel").GetText();
var unfocusedLabelText = App.FindElement("unfocusedLabel").GetText();

Assert.That(focusedLabelText, Is.EqualTo("Focused: true"));
Assert.That(unfocusedLabelText, Is.EqualTo("Unfocused: true"));
}
}
}
#endif
50 changes: 39 additions & 11 deletions src/Core/src/Handlers/DatePicker/DatePickerHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Microsoft.Maui.Handlers
public partial class DatePickerHandler : ViewHandler<IDatePicker, MauiDatePicker>
{
DatePickerDialog? _dialog;
(int year, int month, int day) _selectedDate;

protected override MauiDatePicker CreatePlatformView()
{
Expand Down Expand Up @@ -52,6 +53,11 @@ protected override void DisconnectHandler(MauiDatePicker platformView)
{
if (_dialog != null)
{
_dialog.DismissEvent -= OnDismissEvent;
_dialog.ShowEvent -= OnShowEvent;
if (OperatingSystem.IsAndroidVersionAtLeast(24))
_dialog.DateSet -= OnDateSet;

_dialog.Hide();
_dialog.Dispose();
_dialog = null;
Expand All @@ -66,14 +72,7 @@ protected override void DisconnectHandler(MauiDatePicker platformView)

protected virtual DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
{
var dialog = new DatePickerDialog(Context!, (o, e) =>
{
if (VirtualView != null)
{
VirtualView.Date = e.Date;
}
}, year, month, day);

var dialog = new DatePickerDialog(Context!, OnDateSet, year, month, day);
return dialog;
}

Expand Down Expand Up @@ -130,6 +129,7 @@ void ShowPickerDialog()
if (_dialog != null && _dialog.IsShowing)
return;

VirtualView.IsFocused = true;
var date = VirtualView.Date;
ShowPickerDialog(date.Year, date.Month - 1, date.Day);
}
Expand All @@ -140,14 +140,42 @@ void ShowPickerDialog(int year, int month, int day)
_dialog = CreateDatePickerDialog(year, month, day);
else
{
EventHandler? setDateLater = null;
setDateLater = (sender, e) => { _dialog!.UpdateDate(year, month, day); _dialog.ShowEvent -= setDateLater; };
_dialog.ShowEvent += setDateLater;
_selectedDate = (year, month, day);
_dialog.ShowEvent += OnShowEvent;
_dialog.DismissEvent += OnDismissEvent;
}

_dialog.Show();
}

void OnDismissEvent(object? sender, EventArgs e)
{
if (VirtualView != null)
{
VirtualView.IsFocused = false;
}

if (_dialog != null)
{
_dialog.DismissEvent -= OnDismissEvent;
}
}

void OnShowEvent(object? sender, EventArgs e)
{
_dialog!.UpdateDate(_selectedDate.year, _selectedDate.month, _selectedDate.day);
_dialog.ShowEvent -= OnShowEvent;
}

void OnDateSet(object? obj, DatePickerDialog.DateSetEventArgs e)
{
if (VirtualView != null)
{
VirtualView.Date = e.Date;
VirtualView.IsFocused = false;
}
}

void HidePickerDialog()
{
_dialog?.Hide();
Expand Down
42 changes: 30 additions & 12 deletions src/Core/src/Handlers/TimePicker/TimePickerHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,45 @@ protected override void DisconnectHandler(MauiTimePicker platformView)
if (_dialog != null)
{
_dialog.Hide();
_dialog.DismissEvent -= OnDismiss;
_dialog = null;
}
}

protected virtual TimePickerDialog CreateTimePickerDialog(int hour, int minute)
{
void onTimeSetCallback(object? obj, TimePickerDialog.TimeSetEventArgs args)
{
if (VirtualView == null || PlatformView == null)
return;
var dialog = new TimePickerDialog(Context!, OnTimeSetCallback, hour, minute, Use24HourView);
dialog.DismissEvent += OnDismiss;

VirtualView.Time = new TimeSpan(args.HourOfDay, args.Minute, 0);
VirtualView.IsFocused = false;
return dialog;
}

if (_dialog != null)
{
_dialog = null;
}
private void OnTimeSetCallback(object? obj, TimePickerDialog.TimeSetEventArgs args)
{
if (VirtualView == null || PlatformView == null)
return;

VirtualView.Time = new TimeSpan(args.HourOfDay, args.Minute, 0);
VirtualView.IsFocused = false;

if (_dialog != null)
{
_dialog.DismissEvent -= OnDismiss;
_dialog = null;
}
}

var dialog = new TimePickerDialog(Context!, onTimeSetCallback, hour, minute, Use24HourView);
private void OnDismiss(object? sender, EventArgs e)
{
if (VirtualView != null)
{
VirtualView.IsFocused = false;
}

return dialog;
if (_dialog != null)
{
_dialog.DismissEvent -= OnDismiss;
}
}

// This is a Android-specific mapping
Expand Down Expand Up @@ -90,6 +106,8 @@ void ShowPickerDialog()
if (VirtualView == null)
return;

VirtualView.IsFocused = true;

var time = VirtualView.Time;
ShowPickerDialog(time.Hours, time.Minutes);
}
Expand Down
Loading