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

Xamarin.Forms如何显示实时时间?Android端DateTime.Now不更新如何解决

问题根因

DateTime.Now是.NET的静态属性,仅在被调用时返回当前系统时间。Xamarin.Forms中如果直接将其绑定到UI,因为没有主动的属性变更通知,UI只会在绑定初始化时读取一次值,后续不会自动刷新,所以看起来是时间没有实时更新。

可行解决方案
  • 方案1:跨平台定时器定时刷新。用Xamarin.Forms内置的定时器按指定间隔更新时间属性,触发属性变更通知刷新UI,适配全平台,实现简单。
  • 方案2:Android端监听系统时间广播。注册系统时间变更、分钟级心跳广播,系统时间变化时自动同步更新,比长时间运行定时器更省电。
  • 方案3:绑定搭配值转换器。自定义IValueConverter在绑定取值时实时读取DateTime.Now,适合对刷新精度要求不高的场景。
实现示例

跨平台通用实现(定时器方案,支持直接获取年/月/日/时/分)

首先实现带通知的ViewModel:

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

public class TimeViewModel : INotifyPropertyChanged
{
    private DateTime _currentTime;
    public DateTime CurrentTime
    {
        get => _currentTime;
        set
        {
            _currentTime = value;
            OnPropertyChanged();
            // 同步通知单个时间字段变更
            OnPropertyChanged(nameof(Year));
            OnPropertyChanged(nameof(Month));
            OnPropertyChanged(nameof(Day));
            OnPropertyChanged(nameof(Hour));
            OnPropertyChanged(nameof(Minute));
        }
    }

    // 直接暴露各时间字段,可单独绑定使用
    public int Year => CurrentTime.Year;
    public int Month => CurrentTime.Month;
    public int Day => CurrentTime.Day;
    public int Hour => CurrentTime.Hour;
    public int Minute => CurrentTime.Minute;

    public TimeViewModel()
    {
        CurrentTime = DateTime.Now;
        // 按1秒间隔刷新,不需要秒级精度可改为60000(1分钟)降低功耗
        Device.StartTimer(TimeSpan.FromSeconds(1), () =>
        {
            CurrentTime = DateTime.Now;
            return true;
        });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML绑定示例:

<ContentPage.BindingContext>
    <local:TimeViewModel />
</ContentPage.BindingContext>

<StackLayout Padding="20">
    <Label Text="{Binding CurrentTime, StringFormat='完整时间:{0:yyyy-MM-dd HH:mm:ss}'}" FontSize="Large"/>
    <Label Text="{Binding Year, StringFormat='年:{0}'}" FontSize="Medium"/>
    <Label Text="{Binding Month, StringFormat='月:{0}'}" FontSize="Medium"/>
    <Label Text="{Binding Day, StringFormat='日:{0}'}" FontSize="Medium"/>
    <Label Text="{Binding Hour, StringFormat='时:{0}'}" FontSize="Medium"/>
    <Label Text="{Binding Minute, StringFormat='分:{0}'}" FontSize="Medium"/>
</StackLayout>

Android端省电优化实现(可选)

在Android项目中注册系统时间广播接收器,不用常驻定时器:

[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionTimeChanged, Intent.ActionTimeTick, Intent.ActionTimezoneChanged })]
public class TimeUpdateReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // 通知Forms层更新时间
        MessagingCenter.Send<object, DateTime>(this, "SysTimeUpdated", DateTime.Now);
    }
}

修改ViewModel逻辑,订阅广播消息更新时间:

public TimeViewModel()
{
    CurrentTime = DateTime.Now;
    MessagingCenter.Subscribe<object, DateTime>(this, "SysTimeUpdated", (sender, newTime) =>
    {
        CurrentTime = newTime;
    });
}
注意事项
  • 页面销毁时需要主动停止定时器、取消MessagingCenter订阅,避免内存泄漏
  • 如果需要时间格式跟随系统地区设置,不要硬写格式化字符串,使用CurrentTime.ToString("f")等系统预设格式即可

内容的提问来源于stack exchange,提问作者Daniel Flores

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:27:03