如何将Android原生TimePicker的选中时间与变更事件传递到Xamarin Forms共享项目
解决方案:将Android原生时间选择器的选中时间传递到Xamarin Forms共享项目
问题分析
现有代码中,Android渲染器已在OnTimeSet方法中更新了Xamarin Forms控件的TimeProperty,但共享项目页面未正确监听该属性变化;同时渲染器内ShowTimePicker方法存在错误代码,且时间显示格式不符合24小时制要求。
步骤1:修正Android原生渲染器代码
移除错误的_dialog.OnTimeSetListener调用,修正时间显示格式为24小时制:
using System; using Android.Content; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))] namespace TimePickerDemo.Droid { public class CustomTimePicker24HRenderer : ViewRenderer<TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener { TimePickerDialog _dialog; public CustomTimePicker24HRenderer(Context context) : base(context) { } Context CurrentContext => Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity; IElementController ElementController => Element as IElementController; public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute) { var time = new TimeSpan(hourOfDay, minute, 0); // 更新Xamarin Forms TimePicker的Time属性 Element.SetValue(TimePicker.TimeProperty, time); // 以24小时制显示选中时间 Control.Text = time.ToString(@"HH\:mm"); ClearFocus(); } protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e) { base.OnElementChanged(e); SetNativeControl(new Android.Widget.EditText(CurrentContext)); if (Control != null) { Control.Click += Control_Click; Control.FocusChange += Control_FocusChange; if (Element != null && !Element.Time.Equals(default(TimeSpan))) // 初始显示24小时制时间 Control.Text = Element.Time.ToString(@"HH\:mm"); else Control.Text = DateTime.Now.ToString("HH:mm"); } } void Control_FocusChange(object sender, 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(); void ShowTimePicker() { if (_dialog == null) // 构造时传入当前渲染器作为时间选择监听器 _dialog = new TimePickerDialog(CurrentContext, this, Element.Time.Hours, Element.Time.Minutes, true); // 更新对话框显示的当前时间 _dialog.UpdateTime(Element.Time.Hours, Element.Time.Minutes); _dialog.Show(); } } }
步骤2:修改XAML,为自定义时间选择器命名
给CustomTimePicker24H添加x:Name,方便页面代码引用:
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" BackgroundColor="White" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:custom="clr-namespace:TimePickerDemo;assembly=TimePickerDemo" x:Class="TimePickerDemo.Views.TimePicker24HPage"> <ContentPage.Content> <StackLayout Padding="30,80,30,0" Spacing="40" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand"> <Label x:Name="LabelTimeText" Text="TimePicker 24H Format" HorizontalOptions="CenterAndExpand" TextColor="Gray" FontSize="20" /> <custom:CustomTimePicker24H x:Name="CustomTimePicker" TextColor="Gray" Format="HH:mm" HeightRequest="40" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand" /> </StackLayout> </ContentPage.Content> </ContentPage>
步骤3:在共享项目页面监听时间变化
订阅自定义时间选择器的PropertyChanged事件,当Time属性更新时同步更新Label显示:
using System; using Xamarin.Forms; namespace TimePickerDemo.Views { public partial class TimePicker24HPage: ContentPage { public TimePicker24HPage() { InitializeComponent(); // 订阅时间选择器的属性变化事件 CustomTimePicker.PropertyChanged += CustomTimePicker_PropertyChanged; } private void CustomTimePicker_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(TimePicker.Time)) { // 将选中时间转为24小时制字符串更新Label var selectedTime = CustomTimePicker.Time; LabelTimeText.Text = selectedTime.ToString(@"HH\:mm"); } } protected override void OnDisappearing() { base.OnDisappearing(); // 取消订阅避免内存泄漏 CustomTimePicker.PropertyChanged -= CustomTimePicker_PropertyChanged; } } }
步骤4:自定义控件(保持现有结构)
无需额外修改,继承TimePicker即可:
namespace TimePickerDemo { public class CustomTimePicker24H : TimePicker { } }
内容的提问来源于stack exchange,提问作者CodingSoft
相关产品推荐
相关产品推荐

