XF项目Android端24小时TimePicker聚焦/失焦事件未触发求助
解决Xamarin.Forms Android端24小时TimePicker焦点事件不触发的问题
我之前在做Xamarin.Forms项目的时候刚好碰到过一模一样的问题!当时折腾了好一阵才找到靠谱的解决办法,分享给你参考下:
问题根源
默认的Android TimePicker渲染器在切换到24小时模式后,原生控件的焦点事件没有正确映射到XF的Focused/Unfocused事件上,尤其是当我们自定义TimePickerDialog来实现24小时选择时,Dialog关闭后不会自动触发Unfocus事件。
具体解决方案
1. 自定义Android渲染器
创建一个继承自TimePickerRenderer的自定义渲染器,手动处理原生控件的焦点事件,并将其映射到XF控件的事件上:
[assembly: ExportRenderer(typeof(TimePicker), typeof(CustomTimePickerRenderer))] namespace YourApp.Droid.Renderers { public class CustomTimePickerRenderer : TimePickerRenderer { protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e) { base.OnElementChanged(e); if (Control != null) { // 订阅原生EditText的焦点变化事件 Control.FocusChange += OnControlFocusChanged; // 设置24小时输入模式 Control.InputType = Android.Text.InputTypes.ClassTime | Android.Text.InputTypes.TimeFlag24Hour; // 自定义TimePickerDialog实现24小时选择 Control.Click += (sender, args) => { var currentTime = Element.Time; var timeDialog = new TimePickerDialog( Context, (dialog, hour, minute) => { Element.Time = new TimeSpan(hour, minute, 0); // 关闭Dialog后手动清除焦点,触发Unfocus事件 Control.ClearFocus(); }, currentTime.Hours, currentTime.Minutes, true // 启用24小时模式 ); timeDialog.Show(); }; } // 订阅/取消订阅XF控件的焦点事件 if (e.OldElement != null) { e.OldElement.Focused -= OnElementFocused; e.OldElement.Unfocused -= OnElementUnfocused; } if (e.NewElement != null) { e.NewElement.Focused += OnElementFocused; e.NewElement.Unfocused += OnElementUnfocused; } } private void OnControlFocusChanged(object sender, Android.Views.View.FocusChangeEventArgs e) { if (e.HasFocus) { Element?.Focus(); } else { Element?.Unfocus(); } } private void OnElementFocused(object sender, FocusEventArgs e) { if (Control != null && !Control.HasFocus) { Control.RequestFocus(); } } private void OnElementUnfocused(object sender, FocusEventArgs e) { if (Control != null && Control.HasFocus) { Control.ClearFocus(); } } protected override void Dispose(bool disposing) { if (disposing && Control != null) { Control.FocusChange -= OnControlFocusChanged; } base.Dispose(disposing); } } }
2. 确保XF端正确订阅事件
在你的XAML或代码后台,确保TimePicker控件正确绑定了Focused和Unfocused事件:
XAML示例:
<TimePicker x:Name="CustomTimePicker" Focused="CustomTimePicker_Focused" Unfocused="CustomTimePicker_Unfocused" />
代码后台示例:
CustomTimePicker.Focused += (sender, e) => { // 处理聚焦逻辑 Console.WriteLine("TimePicker 已聚焦"); }; CustomTimePicker.Unfocused += (sender, e) => { // 处理失焦逻辑 Console.WriteLine("TimePicker 已失焦"); };
3. 额外注意事项
- 检查父布局的
Focusable和FocusableInTouchMode属性,避免其他控件抢占焦点; - 测试时确保没有其他自定义渲染器或第三方库干扰TimePicker的焦点事件;
- 如果使用了MVVM模式,可以通过行为(Behavior)来绑定焦点事件,效果是一样的。
我当时就是用这套方案解决的问题,Android端的Focused和Unfocused事件都能正常触发了,亲测有效!
内容的提问来源于stack exchange,提问作者Ashish Kumar
相关产品推荐
相关产品推荐

