繁体   English   中英

Xamarin Android倒计时MVVMCross

[英]Countdown MVVMCross with Xamarin Android

我想在MVVMCross的droid项目中为textview创建一个倒数计时器。

这是我的解决方案: 在此处输入图片说明

我对此解决方案有一个小问题,因为我无法使用System.Threading.Timer,因此我需要创建自己的类。

但是我不知道怎么做,因为我自己的类必须在业务项目中,并且必须使用UI项目的.Core项目来调用该类。

你能帮助我吗 ?

谢谢

我做到了,但不起作用:SelfieBox.Business中的TimerCustom类

public class TimerCustom
{
    private int _valueOfTimer;
    private bool _timerRunning;

    public int ValueOfTimer
    {
        get { return _valueOfTimer; }
        set { _valueOfTimer = value; }
    }

    public TimerCustom(int valueOfTimer)
    {
        _valueOfTimer = valueOfTimer;
    }

    public async Task<TimerCustom> Start()
    {
        if (!_timerRunning)
        {
            _timerRunning = true;
            await RunTimer();
        }

        return this;
    }

    private async Task RunTimer()
    {
        while (_timerRunning && _valueOfTimer > 0)
        {
            await Task.Delay(1);

            _valueOfTimer--;

            if (_valueOfTimer == 0)
            {
                _timerRunning = false;
            }
        }
    }
}

SelfieBox.Core中的ViewModel:

public class SecondStep_Photo_ViewModel : MvxViewModel
{
    private Business.Models.TimerCustom _timerCustom;

    #region Prop => Value Of Timer
    private int _valueOfTimer;

    public int ValueOfTimer
    {
        get { return _valueOfTimer; }
        set { _valueOfTimer = value; }
    }
    #endregion


    public SecondStep_Photo_ViewModel()
    {
        _timerCustom = new Business.Models.TimerCustom(5);
        _timerCustom.Start();

        ValueOfTimer = _timerCustom.ValueOfTimer;
    }
}

我的看法是在SelfieBox.Droid中:

...<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/TxtTimer"
    android:textSize="200dp"
    android:textStyle="bold"
    android:gravity="center"
    android:visible="false" 
    android:layout_centerInParent="true" 
    local:MvxBind="Text ValueOfTimer; Visible DisplayTimer"/>

我的计时器下降得很好,但是它没有显示在屏幕上

问题在于,在ViewModel中,您永远不会对计时器中的更改做出反应,也永远不会调用RaisePropertyChanged

因此,我改为将您的计时器更改为以下形式:

public class Timer
{
    private bool _started;

    public int Time { get; private set; }
    public event EventHandler<int> TimeElapsed;

    public Timer(int startTime)
    {
        Time = startTime;
    }

    public async Task StartAsync(CancellationToken token = default(CancellationToken))
    {
        if (_started) return;

        _started = true;

        while (_started && Time > 0)
        {
            // wait 1000 ms
            await Task.Delay(1000, token).ConfigureAwait(false);
            if (--Time == 0)
            {
                _started = false;
            }
            TimeElapsed?.Invoke(this, Time);
        }
    }
}

这样,您可以在事件中公开相应地更新ViewModel:

var timer = new Timer(5);
timer.TimeElapsed += (s, t) => ValueOfTimer = t;
timer.StartAsync();

确保ValueOfTimer引发PropertyChanged:

private int _valueOfTimer;

public int ValueOfTimer
{
    get { return _valueOfTimer; }
    set { 
        _valueOfTimer = value;
        RaisePropertyChanged(() => ValueOfTimer);
    }
}

您可以使用Task.Delay获得与Timer相同的效果。 有关更多详细信息,请参见以下答案: PCL .NET 4.5 Timer

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM