简体   繁体   English

在 Xamarin 中,如何在 1 秒内更改按钮的背景颜色并再次将其恢复为原始颜色?

[英]In Xamarin, how can I change the background color of a button for just 1 second and return it again to its original color?

I'm developing a little app in Xamarin and I want to change the background color of a button just for 1 second when the user presses it.我正在 Xamarin 中开发一个小应用程序,我想在用户按下按钮时将按钮的背景颜色更改1 秒钟 The code I'm trying to use is the following:我尝试使用的代码如下:

var auxColor = btnCancel.BackgroundColor;    // saving the original color (btnCancel is the button name)
btnCancel.BackgroundColor = Color.Red;       // changing the color to red
Task.Delay(1000).Wait();                     // waiting 1 second            
btnCancel.BackgroundColor = auxColor;        // restoring the original color

But what I get is the following sequence:但我得到的是以下序列:

1- Saving the original color 1-保存原始颜色
2- WAITING 1 SECOND 2-等待 1 秒
3 Changing the color to red 3 将颜色更改为红色
4 Immediately restoring the color 4 立即恢复颜色

Does anybody know how to solve this problem?有谁知道如何解决这个问题?

You can use the Device.StartTimer in the following manner.您可以通过以下方式使用Device.StartTimer

In your button click event:在您的按钮单击事件中:

private void OnButtonClicked(object sender, EventArgs e)
{                    
    var auxColor = btnCancel.BackgroundColor;    // saving the original color 
    btnCancel.BackgroundColor = Color.Red; 

    Device.StartTimer(TimeSpan.FromSeconds(1), () =>
    {
        btnCancel.BackgroundColor = auxColor;             
        return false;
    });
}

To interact with UI elements you can use BeginInvokeOnMainThread like:要与 UI 元素交互,您可以使用BeginInvokeOnMainThread ,例如:

Device.StartTimer (new TimeSpan (0, 0, 1), () =>
{
    // do something every 1 second
    Device.BeginInvokeOnMainThread (() => 
    {
      // interact with UI elements
    });
    return true; // runs again, or false to stop
});

See Device.StartTimer docs.请参阅Device.StartTimer文档。

Looks like you are calling the steatements in a method executed by the main thread, which is also responsible for rendering.看起来您正在调用由主线程执行的方法中的语句,该主线程也负责渲染。 This means your statement这意味着你的陈述

Task.Delay(1000).Wait();                     // waiting 1 second   

blocks rendering, so your change will not be visible.阻止渲染,因此您的更改将不可见。

There are different possible approaches to solve your problem, simplest approach would be using an async method, to allow the UI thread to continue in background:有多种可能的方法来解决您的问题,最简单的方法是使用异步方法,以允许 UI 线程在后台继续:

private async void blink()
{
    var auxColor = btnCancel.BackgroundColor;    // saving the original color (btnCancel is the button name)
    btnCancel.BackgroundColor = Color.Red;       // changing the color to red
    await Task.Delay(1000)                       // waiting 1 second            
    btnCancel.BackgroundColor = auxColor;        // restoring the original color
}

Another possible solution would be to setting the original color after the delay was finished using the original (UI) thread context again:另一种可能的解决方案是在延迟完成后再次使用原始(UI)线程上下文设置原始颜色:

var auxColor = btnCancel.BackgroundColor;        // saving the original color (btnCancel is the button name)
btnCancel.BackgroundColor = Color.Red;           // changing the color to red
Task.Delay(1000).ContinueWith((T) =>             // waiting 1 second  
    {
        btnCancel.BackgroundColor = auxColor;    // restoring the original color
    }, TaskScheduler.FromCurrentSynchronizationContext());

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

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