C# 禁用Android双击Xamarin表单标签

C# 禁用Android双击Xamarin表单标签,c#,android,xaml,xamarin.forms,gesture-recognition,C#,Android,Xaml,Xamarin.forms,Gesture Recognition,嘿,我正在处理Xamarin表单,我正在处理android双击的问题 我的问题是,我正在使用标签作为按钮-当我快速单击此按钮时,应用程序将崩溃。我想通过在单击后禁用轻敲来防止这种情况 我的标签在XAML中定义如下: <Label x:Name="LabelName" Text="LabelText"/> public abstract class ThrottlingListener : Java.Lang.Object { readonly TimeSpa

嘿,我正在处理Xamarin表单,我正在处理android双击的问题

我的问题是,我正在使用标签作为按钮-当我快速单击此按钮时,应用程序将崩溃。我想通过在单击后禁用轻敲来防止这种情况

我的标签在XAML中定义如下:

<Label x:Name="LabelName" Text="LabelText"/>
public abstract class ThrottlingListener : Java.Lang.Object
    {
        readonly TimeSpan timeout;

        protected ThrottlingListener( TimeSpan timeout = default(TimeSpan))
        {
            this.timeout = timeout == TimeSpan.Zero ? TimeSpan.FromSeconds(1) : timeout;
        }

        protected bool IsThrottling()
        {
            var now = DateTime.UtcNow;
            if (now - LastClick < timeout)
            {
                return true;
            }
            LastClick = now;
            return false;
        }

        protected DateTime LastClick{ get; private set;}

        protected void DisableView(View view)
        {
            view.Enabled = false;
            view.PostDelayed (() => 
            {
                view.Enabled = true;
            }, (long)timeout.TotalMilliseconds);
        }
    }

    public class ThrottlingOnClickListener : ThrottlingListener, View.IOnClickListener
    {
        readonly Action onClick;

        public ThrottlingOnClickListener(Action onClick, TimeSpan timeout = default(TimeSpan)) : base(timeout)
        {
            this.onClick = onClick;
        }       

        public void OnClick(View view)
        {
            if (IsThrottling())
                return;

            DisableView (view);
            onClick ();
        }

    }

您可以使用外部布尔值来避免这种情况(另外,不确定,但暂时禁用标签可能会起作用):

然后:

LabelName.GestureRecognizers.Add((new TapGestureRecognizer
{
  Command = new Command(async o =>
  {
     if(this.disable)
       return;

     this.disable = true;

    await Navigation.PopToRootAsync();

    this.disable = false;
 })
}));

您需要执行一个将禁用视图的操作。您可以添加可配置的超时来禁用它。 您可以为“单击”或“视图”实现它,并添加任何其他控制压力机的方法。 您的代码应该如下所示:

<Label x:Name="LabelName" Text="LabelText"/>
public abstract class ThrottlingListener : Java.Lang.Object
    {
        readonly TimeSpan timeout;

        protected ThrottlingListener( TimeSpan timeout = default(TimeSpan))
        {
            this.timeout = timeout == TimeSpan.Zero ? TimeSpan.FromSeconds(1) : timeout;
        }

        protected bool IsThrottling()
        {
            var now = DateTime.UtcNow;
            if (now - LastClick < timeout)
            {
                return true;
            }
            LastClick = now;
            return false;
        }

        protected DateTime LastClick{ get; private set;}

        protected void DisableView(View view)
        {
            view.Enabled = false;
            view.PostDelayed (() => 
            {
                view.Enabled = true;
            }, (long)timeout.TotalMilliseconds);
        }
    }

    public class ThrottlingOnClickListener : ThrottlingListener, View.IOnClickListener
    {
        readonly Action onClick;

        public ThrottlingOnClickListener(Action onClick, TimeSpan timeout = default(TimeSpan)) : base(timeout)
        {
            this.onClick = onClick;
        }       

        public void OnClick(View view)
        {
            if (IsThrottling())
                return;

            DisableView (view);
            onClick ();
        }

    }
公共抽象类ThrottlingListener:Java.Lang.Object
{
只读时间间隔超时;
受保护的ThrottlingListener(TimeSpan超时=默认值(TimeSpan))
{
this.timeout=timeout==TimeSpan.Zero?TimeSpan.FromSeconds(1):超时;
}
受保护的布尔IsThrottling()
{
var now=DateTime.UtcNow;
如果(现在-上次单击<超时)
{
返回true;
}
LastClick=现在;
返回false;
}
受保护的DateTime LastClick{get;private set;}
受保护的无效禁用视图(视图)
{
view.Enabled=false;
view.PostDelayed(()=>
{
view.Enabled=true;
},(长)超时。总毫秒数);
}
}
公共类ThrottlingOnClickListener:ThrottlingListener,View.IOnClickListener
{
只读操作onClick;
公共节流nclicklistener(Action onClick,TimeSpan timeout=default(TimeSpan)):base(timeout)
{
this.onClick=onClick;
}       
公共void OnClick(视图)
{
if(IsThrottling())
返回;
禁用视图(视图);
onClick();
}
}

在Android上,用户界面会注册多个点击,并将它们排成队列,一个接一个地执行。因此,双击按钮可能会执行两次命令,并导致意外行为。最简单的方法是让命令观察bool属性并打开/关闭该属性。像这样的,

SomeCommand = new Command (OnCommand,(x)=> CanNavigate);

async void OnCommand (object obj)
{
        CanNavigate = false;

        await CurrentPage.DisplayAlert ("Hello", "From intelliAbb", "OK");

        CanNavigate = true;

}
您可以在

上查看完整的示例,下面是我在C#中所做的:


使用此解决方案,您仍然会收到多个点击噪音。但这是另一个问题,对吗?

最简单的方法是禁用触发tap事件的元素

您可以通过以下示例实现这一点:

var tapRecognizer = new TapGestureRecognizer();
tapRecognizer.Tapped += async (s,e) => 
{
   ((View)s).IsEnabled = false; // or reference the view directly if you have access to it
   await Navigation.PopToRootAsync();
   ((View)s).IsEnabled = true;
};
theLabel.GestureRecognizers.Add(tapRecognizer);

单击按钮时,只需检查应用程序是否正忙

 if (IsBusy)
            return;

如果在其中的某个地方抛出异常,并且从未调用您的启用true,那么会发生什么情况?为了安全起见,您可以使用tryf块将其包围。因此,如果您询问mruse“NumberOfTapRequired”属性,您应该在此处处理该异常
 if (IsBusy)
            return;