【问题标题】:Animate label without resetting timeout duration动画标签而不重置超时持续时间
【发布时间】:2020-12-05 08:53:48
【问题描述】:

我有以下方法可以为标签设置 20 秒的动画。

    public class BlinkTriggerBehavior : Behavior<Label>
{
    CancellationTokenSource tokenSource = new CancellationTokenSource();
    protected override void OnAttachedTo(Label bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.PropertyChanged += Animate; // binding property changed event
    }
    private async void Animate(object obj, PropertyChangedEventArgs e)
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        if (e.PropertyName == "ClassId")
        {
            VisualElement sender = obj as VisualElement;
            var parentAnimation = new Animation();
            var scaleUpAnimation = new Animation(d => sender.Scale = d, 1, 1.2, Easing.SpringIn);
            var fadeOutAnimation = new Animation(d => sender.Opacity = d, 1, 0, Easing.Linear);
            var scaleDownAnimation = new Animation(d => sender.Scale = d, 1.2, 1, Easing.SpringOut);
            var fadeInAnimation = new Animation(d => sender.Opacity = d, 0, 1, Easing.Linear);
            parentAnimation.Add(0, 0.5, fadeOutAnimation);
            parentAnimation.Add(0, 0.5, scaleUpAnimation);
            parentAnimation.Add(0.5, 1, scaleDownAnimation);
            parentAnimation.Add(0.5, 1, fadeInAnimation);
            parentAnimation.Commit(sender, "BlinkingVisualElement", 16, 800, repeat: () => true);
            await Task.Delay(20000);
            parentAnimation.Commit(sender, "BlinkingVisualElement", 16, 800, repeat: () => false);
        }

    }
    protected override void OnDetachingFrom(Label bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.PropertyChanged -= Animate;
    }
}

这个方法可以在 20 秒内被多次调用。如果调用一次,它可以正常工作并为标签设置整整 20 秒的动画,并在触发第二次调用之前等待 20 秒。每当触发此方法时,我希望它动画 20 秒。

现在发生了什么

我第一次调用了这个方法

上午 9:00:00

动画持续到 9:00:20

如果我第二次调用该方法

上午 9:00:12

它仍然只动画到 9:00:20(仅 8 秒)。我希望它动画到 9:00:32

基本上我想重置计时器并在调用此方法时显示完整的 20 秒动画。

【问题讨论】:

  • 您是否尝试使用 CancellationToken 将此方法的内容包装在 Task.Run 中?这是使用它的经典案例。您在重新进入此方法时在 CancellationToken 上调用 Cancel。
  • 你能发个代码sn-p吗。我尝试将动画代码放入Task.Run中,并带有取消令牌。但不起作用
  • 我的解决方案对您有用吗?如果是,请您接受(点击此答案左上角的☑️),以便我们可以帮助更多有相同问题的人:)。
  • @JackHua-MSFT 抱歉耽搁了。我正在尝试不同的方法来获得解决方案。你的回答对我不起作用。我正在编辑我的问题以发布完整的类代码。我正在使用 Behavior 使标签动画化。请检查已编辑的问题并尝试给我一个解决方案。您的支持很重要..谢谢
  • 为什么我的解决方案不适合你?

标签: c# xamarin xamarin.forms async-await xamarin.android


【解决方案1】:

您可以使用System.Timers.Timer 在延迟一段时间后执行任务并重置计时器以重置延迟:

public partial class MainPage : ContentPage
{
    System.Timers.Timer Timer1 { get; set; }

    int count = 0;
    public MainPage()
    {
        InitializeComponent();

    }


    private async void start(object sender, EventArgs e)
    {

        //VisualElement sender = obj as VisualElement;
        //var parentAnimation = new Animation();
        //var fadeOutAnimation = new Animation(d => sender.Opacity = d, 1, 0, Easing.Linear);
        //var fadeInAnimation = new Animation(d => sender.Opacity = d, 0, 1, Easing.Linear);
        //parentAnimation.Add(0, 0.5, fadeOutAnimation);
        //parentAnimation.Add(0.5, 1, fadeInAnimation);
        //parentAnimation.Add(0, 0.5, fadeOutAnimation);
        //parentAnimation.Add(0.5, 1, fadeInAnimation);
        //parentAnimation.Add(0, 0.5, fadeOutAnimation);
        //parentAnimation.Add(0.5, 1, fadeInAnimation);
        //parentAnimation.Add(0, 0.5, fadeOutAnimation);
        //parentAnimation.Add(0.5, 1, fadeInAnimation);
        //parentAnimation.Commit(sender, "BlinkingVisualElement", 16, 800, repeat: () => true);

        Console.WriteLine("start");

        if (Timer1 != null)
        {
            Timer1.Stop();
            Timer1.Dispose();
        }

        Timer1 = new System.Timers.Timer();
        //count every 1 second
        Timer1.Interval = 1000;
        Timer1.Enabled = true;

        //reset count
        count = 0;

        Timer1.Start();

        Timer1.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) =>
        {

            Device.BeginInvokeOnMainThread(() =>
            {
                count++;

                //10 here is the delay time
                if (count == 20)
                {
                    Console.WriteLine("finish");
                    
                    //parentAnimation.Commit(sender, "BlinkingVisualElement", 16, 800, repeat: () => false);

                    Timer1.Stop();
                    Timer1.Dispose();
                }
                else
                {
                    Console.WriteLine("current count(seconds):" + count);
                }

            });
        };
    }   
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-14
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    相关资源
    最近更新 更多