【问题标题】:Disable Android double tap on Xamarin Forms Label在 Xamarin 表单标签上禁用 Android 双击
【发布时间】:2016-06-14 03:01:11
【问题描述】:

嘿,我正在使用 Xamarin Forms,我正在处理 android 双击的问题。

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

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

<Label x:Name="LabelName" Text="LabelText"/>

我的代码隐藏是这样的:

LabelName.GestureRecognizers.Add((new TapGestureRecognizer
{
  Command = new Command(async o =>
  {
    await Navigation.PopToRootAsync();
  })
}));

【问题讨论】:

  • 使用“NumberOfTapRequired”属性

标签: c# android xaml xamarin.forms gesture-recognition


【解决方案1】:

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

//On the form, so you can use a reference to This, else this is a value variable and will be copied and false always
bool disable = false; 

然后:

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

     this.disable = true;

    await Navigation.PopToRootAsync();

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

【讨论】:

    【解决方案2】:

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

    SomeCommand = new Command (OnCommand,(x)=> CanNavigate);
    
    async void OnCommand (object obj)
    {
            CanNavigate = false;
    
            await CurrentPage.DisplayAlert ("Hello", "From intelliAbb", "OK");
    
            CanNavigate = true;
    
    }
    

    你可以在https://intelliabb.com/2017/02/18/handling-multiple-taps-in-xamarin-forms-on-android/查看完整的例子

    【讨论】:

      【解决方案3】:

      最简单的方法是禁用触发点击事件的元素。

      您可以通过以下示例实现此目的:

      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);
      

      【讨论】:

      • 如果在某处抛出异常并且您的使能 true 从未被调用,会发生什么?
      • 为了安全起见,你可以用 tryf 块包围它。
      • 所以如果你问先生,你应该在这里处理
      【解决方案4】:

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

      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 ();
              }
      
          }
      

      【讨论】:

        【解决方案5】:

        这是我在 C# 中所做的:

        private static object _tappedLockObject = new object();
        private static bool _tapped = false;
        
        private void tapHandler()
        {
            // one-at-a-time access to this block prevents duplicate concurrent requests:
            lock(_tappedLockObject)
            {
                if(_tapped) return;
                _tapped = true;
            }
            handleTap();
        }
        
        private void reenableTap()
        {
            _tapped = false;
        }
        

        使用此解决方案,您仍会收到多次点击噪音。但这是一个不同的问题,对吧?

        【讨论】:

          【解决方案6】:

          点击按钮时检查应用程序是否忙碌

           if (IsBusy)
                      return;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-01-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-20
            • 1970-01-01
            • 2023-04-08
            相关资源
            最近更新 更多