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

Xamarin.Android中用户登录时在TextView显示计时器的实现方法

Got it, let's tackle this timer display for your logged-in users in Xamarin.Android. Based on the code you shared, here's a step-by-step implementation that fits with your existing setup:

实现登录后计时器显示的方案

1. 完善ViewModel层(DashboardViewModel)

Since you're using a ViewModel pattern (from your LoginViewModel code), we'll add timer logic to your Dashboard page's ViewModel. This keeps the UI and business logic separated, and ensures clean lifecycle management.

using System;
using System.Timers;
using System.ComponentModel;

public class DashboardViewModel : INotifyPropertyChanged
{
    private Timer _updateTimer;
    private TimeSpan _totalWorkTime;
    private DateTime _loginTimestamp;

    // 绑定到TextView的显示文本
    public string WorkTimerText
    {
        get => $"Dzisiaj pracujesz już:\n{_totalWorkTime:hh\\:mm\\:ss}";
        set => OnPropertyChanged(nameof(WorkTimerText));
    }

    public DashboardViewModel()
    {
        // 获取登录时记录的时间(从你的_appVariables全局变量中)
        _loginTimestamp = _appVariables.logDate;
        StartTimer();
    }

    private void StartTimer()
    {
        // 每秒更新一次计时器
        _updateTimer = new Timer(1000);
        _updateTimer.Elapsed += OnTimerTick;
        // 先计算初始时长,避免延迟显示
        UpdateWorkDuration();
        _updateTimer.Start();
    }

    private void OnTimerTick(object sender, ElapsedEventArgs e)
    {
        UpdateWorkDuration();
        // 必须在主线程更新UI,避免跨线程异常
        Android.App.Application.SynchronizationContext.Post(_ => 
        {
            OnPropertyChanged(nameof(WorkTimerText));
        }, null);
    }

    private void UpdateWorkDuration()
    {
        _totalWorkTime = DateTime.Now - _loginTimestamp;
    }

    // 清理计时器,防止内存泄漏
    public void DisposeTimer()
    {
        _updateTimer?.Stop();
        _updateTimer?.Dispose();
    }

    // INotifyPropertyChanged实现,用于通知UI更新
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 绑定View层(DashboardActivity)

Next, connect the ViewModel to your Dashboard Activity and handle the UI binding, plus lifecycle events to clean up the timer:

using Android.App;
using Android.OS;
using Android.Widget;

[Activity(Label = "Dashboard")]
public class DashboardActivity : Activity
{
    private DashboardViewModel _viewModel;
    private TextView _timeTextView;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Dashboard); // 替换成你的Dashboard布局文件名

        // 找到布局中的TextView
        _timeTextView = FindViewById<TextView>(Resource.Id.timeTextView);
        // 初始化ViewModel
        _viewModel = new DashboardViewModel();
        // 绑定属性变化事件
        _viewModel.PropertyChanged += ViewModel_PropertyChanged;
        // 设置初始文本
        _timeTextView.Text = _viewModel.WorkTimerText;
    }

    private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(_viewModel.WorkTimerText))
        {
            _timeTextView.Text = _viewModel.WorkTimerText;
        }
    }

    // 页面销毁时清理计时器和事件绑定
    protected override void OnDestroy()
    {
        base.OnDestroy();
        _viewModel.DisposeTimer();
        _viewModel.PropertyChanged -= ViewModel_PropertyChanged;
    }

    // 可选:页面暂停时停止计时器,恢复时重启
    protected override void OnPause()
    {
        base.OnPause();
        _viewModel.DisposeTimer();
    }

    protected override void OnResume()
    {
        base.OnResume();
        _viewModel.StartTimer();
    }
}

3. 关键注意事项

  • 线程安全:Timer的Elapsed事件运行在后台线程,所以必须用SynchronizationContext.Post(或RunOnUiThread)切换到主线程更新UI,否则会抛出跨线程异常。
  • 内存泄漏防护:Always stop and dispose the timer, plus unbind the PropertyChanged event when the activity is destroyed—this prevents memory leaks from lingering timer references.
  • 时间格式化:The hh\\:mm\\:ss format displays hours, minutes, and seconds. If you need to include days, use %d\\:hh\\:mm\\:ss instead.
  • 全局变量验证:Ensure _appVariables.logDate is correctly set to the user's login time in your LoginViewModel (your existing code already does this, double-check it's not null/empty).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:28:22