You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:50:02