簡體   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