【问题标题】:Long Press duration on Xamarin FormsXamarin Forms 上的长按持续时间
【发布时间】:2020-07-03 04:19:37
【问题描述】:

Xamarin Forms 中有没有一种方法可以自定义 Android 和 iOS 的长按持续时间?我相信每个平台的默认持续时间是 1 秒,但我的一些用户一直抱怨长按事件在我的应用程序中滚动浏览列表等时触发得太快。所以我很想能够在每个平台上说 2 秒。有什么想法吗?

理想情况下,我想通过增加触发长按事件之前的持续时间来解决此问题。如果这不可能,是否可以使用计时器实现我自己的长按?我已经看到一个很好的例子,一个按钮使用行为和按钮的 Pressed/Released 事件,但理想情况下,我希望此代码适用于任何控件,而不仅仅是按钮和其他控件没有 Pressed/Released 事件。

谢谢!

【问题讨论】:

  • 您好,请查看alexdunn.org/2017/12/27/…
  • 您好,感谢您的评论。我已经有代码可以像你的例子一样长按。我想要做的是能够自定义用户在长按事件被触发之前按下的时间长度。

标签: xamarin.forms


【解决方案1】:

iOS 中,您可以更改 UILongPressGestureRecognizer 的 MinimumPressDuration 来实现。

这是手势必须按下的最短时间,以秒为单位 被认可。默认值为 0.5。

代码是:

public iOSLongPressedEffect()
{
    _longPressRecognizer = new UILongPressGestureRecognizer(HandleLongClick);
    _longPressRecognizer.MinimumPressDuration = 5;
}

Android 中,您似乎无法直接更改持续时间。您必须在方法OnTouchListener 中实现自己的逻辑才能实现。

看看这些线程可能会有所帮助:

change-long-click-delay

android-how-to-increase-long-press-time

how-can-i-increase-the-clicktime

顺便说一句,在 Xamarin.forms 的 Github 中的 this issue 中,说将来会添加一个 LongPressGestureRecognizer api。

【讨论】:

  • 感谢您提供的信息!这帮助我克服了我遇到的问题。
【解决方案2】:

我已将行为附加到按钮以获取长按和点击手势

public class LongPressBehavior : Behavior<Button>
{
    private static readonly object _syncObject = new object();

    private Timer _timer;
    private volatile bool _isReleased;
    private object _context;

    public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(LongPressBehavior), default(ICommand));
    public static readonly BindableProperty EarlyReleaseCommandProperty = BindableProperty.Create(nameof(EarlyReleaseCommand), typeof(ICommand), typeof(LongPressBehavior), default(ICommand));
    public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(nameof(CommandParameter), typeof(object), typeof(LongPressBehavior));
    public static readonly BindableProperty DurationProperty = BindableProperty.Create(nameof(Duration), typeof(int), typeof(LongPressBehavior), 1000);

    public object CommandParameter
    {
        get => GetValue(CommandParameterProperty);
        set => SetValue(CommandParameterProperty, value);
    }

    public ICommand Command
    {
        get => (ICommand)GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    public ICommand EarlyReleaseCommand
    {
        get => (ICommand)GetValue(EarlyReleaseCommandProperty);
        set => SetValue(EarlyReleaseCommandProperty, value);
    }

    public int Duration
    {
        get => (int)GetValue(DurationProperty);
        set => SetValue(DurationProperty, value);
    }

    protected override void OnAttachedTo(ImageButton bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.Pressed += Button_Pressed;
        bindable.Released += Button_Released;
    }

    protected override void OnDetachingFrom(ImageButton bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.Pressed -= Button_Pressed;
        bindable.Released -= Button_Released;
    }

    private void DeInitializeTimer()
    {
        lock (_syncObject)
        {
            if (_timer == null)
            {
                return;
            }
            _timer.Change(Timeout.Infinite, Timeout.Infinite);
            _timer.Dispose();
            _timer = null;
        }
    }

    private void InitializeTimer()
    {
        lock (_syncObject)
        {
            _timer = new Timer(Timer_Elapsed, null, Duration, Timeout.Infinite);
        }
    }

    private void Button_Pressed(object sender, EventArgs e)
    {
        _isReleased = false;
        _context = (sender as ImageButton)?.BindingContext;
        InitializeTimer();
    }

    private void Button_Released(object sender, EventArgs e)
    {
        if (!_isReleased)
        {
            EarlyReleaseCommand?.Execute(CommandParameter);
        }
        _isReleased = true;
        _context = null;
        DeInitializeTimer();
    }

    protected virtual void OnLongPressed()
    {
        if (Command != null && Command.CanExecute(CommandParameter))
        {
            if (CommandParameter == null && Command.CanExecute(_context))
            {
                Command.Execute(_context);
                return;
            }
            Command.Execute(CommandParameter);
        }
    }

    public LongPressBehavior()
    {
        _isReleased = true;
    }

    private void Timer_Elapsed(object state)
    {
        DeInitializeTimer();
        if (_isReleased)
        {
            return;
        }
        _isReleased = true;
        Device.BeginInvokeOnMainThread(OnLongPressed);
    }
}

您可以将其用作:

<Button Text="Long Press Me!">
    <Button.Behaviors>
        <behaviors:LongPressBehavior Command="{Binding LongPressCommand}" EarlyReleaseCommand="{Binding TapCommand}" Duration="5000" />
    </Button.Behaviors>
</Button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 2020-04-10
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多