问题描述
我尝试实现此处提供的24小时Time Picker
XF项目中的24小时TimePicker .
I tried implementing 24 Hour Time Picker
as given here 24 Hour TimePicker in XF project.
但是它不会在Android上触发Focus
和Unfocused
事件.有人实现了吗?
But it doesn't fire the Focus
and Unfocused
event on Android. Has anyone implemented this?
推荐答案
说明
此自定义控件的作者忘了在Android自定义渲染器中触发Focused
和Unfocused
.
我们可以通过在FocusChanged
触发时从Android Custom Renderer调用ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, [true/false]);
来触发这些事件.
We can fire these events by calling ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, [true/false]);
from the Android Custom Renderer when FocusChanged
fires.
这个自定义的Android控件一旦设置了时间也不会清除焦点,因此我们也将ClearFocus()
添加到OnTimeSet
.
This custom Android control also doesn't clear focus once the time is set, so we'll add ClearFocus()
to OnTimeSet
too.
由于该示例是使用Xamarin.Forms v2.4编写的,因此,如果您继续使用Xamarin.Forms v2.4,这就是答案.
Because the sample was written in Xamarin.Forms v2.4, here's the answer if you are continuing with 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 2.5+答案
Xamarin.Forms v2.5已弃用Forms.Context
,并且还要求重载的构造函数用于自定义渲染器.
Xamarin.Forms 2.5+ Answer
Xamarin.Forms v2.5 deprecated Forms.Context
and also requires an overloaded constructor to be used for Custom Renderers.
要替换Forms.Context
,我们需要安装 Plugin.CurrentActivity NuGet软件包.
To replace Forms.Context
, we'll need to install the 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();
}
}
}
这篇关于24小时TimePicker具有焦点和非焦点事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!