简体   繁体   English

Xamarin.Android Timer更新UI - runOnUiThread

[英]Xamarin.Android Timer to update the UI - runOnUiThread

I'm developing a Xamarin.Android app that references a portable class library with viewmodels. 我正在开发一个Xamarin.Android应用程序,它引用了一个带有viewmodels的可移植类库。 MvvmCross is being used. 正在使用MvvmCross。 I need a Timer that updates the UI every time it "ticks". 我需要一个Timer,每次“滴答”时都会更新UI。 I just can't seem to get it to update the UI. 我似乎无法让它更新UI。 It is performing the Tick method every second as confirmed by using the debugger. 正如使用调试器确认的那样,它每秒执行一次Tick方法。 I need to use the RunOnUiThread method but I'm just unsure how to implement it in Xamarin. 我需要使用RunOnUiThread方法,但我不确定如何在Xamarin中实现它。 A code example causing tick to update the UI thread would be appreciated. 将会感谢导致tick更新UI线程的代码示例。

Ticker.cs: Ticker.cs:

using System;
using Pong.Core.Models;
using Pong.Core.ViewModels;
using System.Threading;

namespace Pong.Droid
{
    public class Ticker
    {
        private readonly Timer _dispatcherTimer;

        private readonly GamePlayViewModel _viewModel;


        public Ticker(GamePlayViewModel viewModel)
        {
            _viewModel = viewModel;
            TimerCallback timerDelegate = new TimerCallback (Tick);
            _dispatcherTimer = new Timer (timerDelegate, null, 0, 1000);
        }



        public void Tick(object state)
        {
            _viewModel.Number++;


            //_viewModel.UpdateBall();
            //_viewModel.UpdatePaddle1();
        }
    }
}

the activity: 活动:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Pong.Core.ViewModels;
using Cirrious.MvvmCross.Droid.Views;
using Android.Content.PM;

namespace Pong.Droid
{
    [Activity (Label = "GamePlayView", ScreenOrientation = ScreenOrientation.Landscape)]            
    public class GamePlayView : MvxActivity
    {
        private GamePlayViewModel _vm;
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            SetContentView (Resource.Layout.GamePlayView);

            _vm = new GamePlayViewModel();
            DataContext = _vm;
            var ticker = new Ticker(_vm);
        }
    }
}

the layout: 布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="40dp"/>
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        local:MvxBind="Text Number" />
</LinearLayout>

the viewmodel: viewmodel:

using Pong.Core.Models;
using System.Diagnostics;
using Cirrious.MvvmCross.ViewModels;


namespace Pong.Core.ViewModels
{
    public class GamePlayViewModel : MvxViewModel
    {
        protected Paddle Paddle1;
        private Paddle _paddle2; // Not yet implemented
        protected StandardBall StandardBall;
        public int Number { get; set; }

        public GamePlayViewModel()
        {
            Paddle1 = new Paddle();
            StandardBall = new StandardBall();
            Number = 1;
        }

        public void UpdatePaddle1()
        {
            switch (Paddle1.DetectWallCollision())
            {
                case "upper":
                    Paddle1.UpperWallHit();
                    break;
                case "lower":
                    Paddle1.LowerWallHit();
                    break;
                case "none":
                    Paddle1.MoveOneFrame();
                    break;
            }
        }

        public void UpdateBall()
        {
            if (StandardBall.DetectWallCollision()) StandardBall.HandleWallCollision();
            StandardBall.MoveOneFrame();
        }

        public void SetPaddleDirection(string direction)
        {
            Paddle1.SetDirection(direction);
        }

        public void StopPaddle()
        {
            Paddle1.StopMoving();
        }
    }
}

You say the Tick method is called regularly. 你说Tick方法是定期调用的。 So your only problem is to update the UI. 因此,您唯一的问题是更新UI。 This can be done with RunOnUIThread in the Tick method: 这可以使用Tick方法中的RunOnUIThread完成:

public void Tick(object state)
{            
    RunOnUiThread (() => _viewModel.Number++);
}

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

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