我尝试在XF项目中实施此处24 Hour TimePicker所提供的24小时Time Picker
。
但它并没有触发Android上的Focus
和Unfocused
事件。有没有人实现过这个?
答案 0 :(得分:3)
此自定义控件的作者忘记在Android自定义渲染器中触发Focused
和Unfocused
。
我们可以在ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, [true/false]);
触发时通过Android自定义渲染器调用FocusChanged
来触发这些事件。
此自定义Android控件在设置时间后也无法清晰对焦,因此我们也会ClearFocus()
添加OnTimeSet
。
因为样本是用Xamarin.Forms v2.4编写的,所以如果你继续使用Xamarin.Forms v2.4,这就是答案。
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using TimePickerDemo.CustomControls;
using TimePickerDemo.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
namespace TimePickerDemo.Droid
{
public class CustomTimePicker24HRenderer : ViewRenderer<Xamarin.Forms.TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable
{
private TimePickerDialog dialog = null;
IElementController ElementController => Element as IElementController;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)
{
base.OnElementChanged(e);
this.SetNativeControl(new Android.Widget.EditText(Forms.Context));
this.Control.Click += Control_Click;
this.Control.Text = DateTime.Now.ToString("HH:mm");
this.Control.KeyListener = null;
this.Control.FocusChange += Control_FocusChange;
}
void Control_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
{
if (e.HasFocus)
{
ShowTimePicker();
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
}
else
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
}
}
void Control_Click(object sender, EventArgs e)
{
ShowTimePicker();
}
private void ShowTimePicker()
{
if (dialog == null)
{
dialog = new TimePickerDialog(Forms.Context, this, DateTime.Now.Hour, DateTime.Now.Minute, true);
}
dialog.Show();
}
public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)
{
var time = new TimeSpan(hourOfDay, minute, 0);
this.Element.SetValue(Xamarin.Forms.TimePicker.TimeProperty, time);
this.Control.Text = time.ToString(@"hh\:mm");
this.ClearFocus();
}
}
}
Xamarin.Forms v2.5已弃用Forms.Context
,并且还需要将重载的构造函数用于自定义渲染器。
要替换Forms.Context
,我们需要安装Plugin.CurrentActivity NuGet Package。
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using TimePickerDemo.CustomControls;
using TimePickerDemo.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
namespace TimePickerDemo.Droid
{
public class CustomTimePicker24HRenderer : ViewRenderer<Xamarin.Forms.TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable
{
private TimePickerDialog dialog = null;
public CustomTimePicker24HRenderer(Context context) : base(context)
{
}
Context CurrentContext => Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;
IElementController ElementController => Element as IElementController;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)
{
base.OnElementChanged(e);
this.SetNativeControl(new Android.Widget.EditText(CurrentContext));
this.Control.Click += Control_Click;
this.Control.Text = DateTime.Now.ToString("HH:mm");
this.Control.KeyListener = null;
this.Control.FocusChange += Control_FocusChange;
}
void Control_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
{
if (e.HasFocus)
{
ShowTimePicker();
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
}
else
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
}
}
void Control_Click(object sender, EventArgs e)
{
ShowTimePicker();
}
private void ShowTimePicker()
{
if (dialog == null)
{
dialog = new TimePickerDialog(CurrentContext, this, DateTime.Now.Hour, DateTime.Now.Minute, true);
}
dialog.Show();
}
public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)
{
var time = new TimeSpan(hourOfDay, minute, 0);
this.Element.SetValue(Xamarin.Forms.TimePicker.TimeProperty, time);
this.Control.Text = time.ToString(@"hh\:mm");
this.ClearFocus();
}
}
}