Xamarin.Android Tap手势和长按手势无法同时使用

我通过子类化RoutingEffect来创建自定义效果,以便在我的Xamarin项目中同时允许LongPressGestureiOS都使用Android

我正在共享项目的Image中的XAML上使用这种效果,而同样的Image也在使用TapGesture,请参见下面的代码:

                <Image x:Name="TapRight" Grid.Row="4" Grid.Column="2"  Source="right64" 
                   VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
                   IsEnabled="{Binding RightEnabled}"
                   Opacity="{Binding RightEnabled,Converter={StaticResource OpacityConverter}}"
                   effects:LongPressEffect.Command="{Binding LongPressGestureCommand}"
                   effects:LongPressEffect.commandparameter="{x:Static common:NavType.Right}">
                <Image.GestureRecognizers>
                    <TapGestureRecognizer 
                        Command="{Binding TapGestureNavCommand}" 
                        NumberOfTapsRequired="1"
                        commandparameter="{x:Static common:NavType.Right}"/>
                </Image.GestureRecognizers>
                <Image.Effects>
                        <effects:LongPressEffect></effects:LongPressEffect>
                </Image.Effects>
            </Image>

这对于iOS来说很好用(当我点击vs长按图像时,我获得了单独的功能),但是对于Android,它只允许我进行长按,并且不执行TapGesture的命令,有关如何解决此问题的任何想法?

注意::如果我使用Button而不是Image,则可以正常使用。但是,我真的很想使用Image

我在下面添加了更多代码以供参考:

共享项目中效果的代码:

using System.Windows.Input;
using Xamarin.Forms;


namespace MyApp.Effects
{

    public class LongPressEffect : RoutingEffect
    {
        public LongPressEffect() : base("Xamarin.LongPressEffect")
        {

        }

        public static readonly BindableProperty CommandProperty =
         BindableProperty.CreateAttached("Command",typeof(ICommand),typeof(LongPressEffect),(object)null,propertyChanged: OnCommandChanged);

        public static ICommand getcommand(BindableObject view)
        {
            return (ICommand)view.Getvalue(CommandProperty);
        }

        public static void SetCommand(BindableObject view,ICommand value)
        {
            view.Setvalue(CommandProperty,value);
        }

        static void OnCommandChanged(BindableObject bindable,object oldValue,object newValue)
        {
            var view = bindable as View;
            if (view == null)
            {
                return;
            }
            ICommand command = (ICommand)newValue;
            if (command != null)
            {
                view.Setvalue(CommandProperty,command);
            }

        }

        public static readonly BindableProperty commandparameterProperty =
            BindableProperty.CreateAttached("commandparameter",typeof(object),propertyChanged: OncommandparameterChanged);

        public static object Getcommandparameter(BindableObject view)
        {
            return (object)view.Getvalue(commandparameterProperty);
        }

        public static void Setcommandparameter(BindableObject view,object value)
        {
            view.Setvalue(commandparameterProperty,value);
        }

        static void OncommandparameterChanged(BindableObject bindable,object newValue)
        {
            var view = bindable as View;
            if (view == null)
            {
                return;
            }
            object commandparameter = (object)newValue;
            if (commandparameter != null)
            {
                view.Setvalue(commandparameterProperty,commandparameter);
            }
        }
    }
}

在iOS中生效的代码:

using System;
using System.ComponentModel;
using MyApp.Effects;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ResolutionGroupName("Xamarin")]
[assembly:ExportEffect (typeof(MyApp.iOS.Effects.LongPressEffect),"LongPressEffect")]
namespace MyApp.iOS.Effects
{
    public class LongPressEffect : PlatformEffect
    {
        private readonly UILongPressGestureRecognizer _longPressGestureRecognizer;
        private bool _attached;
        public LongPressEffect()
        {
            _longPressGestureRecognizer = new UILongPressGestureRecognizer(HandleLongClick);
            _attached = false;

        }

        protected override void OnAttached()
        {
            if (!_attached)
            {
                Container.AddGestureRecognizer(_longPressGestureRecognizer);
                _attached = true;
            }
        }

        private void HandleLongClick()
        {
            if (_longPressGestureRecognizer.State == UIGestureRecognizerState.Ended)
                // Only execute when the press is ended.
            {
                var command = MyApp.Effects.LongPressEffect.getcommand(Element);
                command?.Execute(MyApp.Effects.LongPressEffect.Getcommandparameter(Element));
            }
        }

        protected override void OnDetached()
        {
            if (_attached)
            {
                Container.RemoveGestureRecognizer(_longPressGestureRecognizer);
                _attached = false;
            }
        }

        protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
        {
            base.OnElementPropertyChanged(args);
        }
    }
}

在Android中生效的代码:

using System;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ResolutionGroupName("Xamarin")]
[assembly: ExportEffect(typeof(MyApp.Droid.Effects.LongPressEffect),"LongPressEffect")]
namespace MyApp.Droid.Effects
{
    public class LongPressEffect: PlatformEffect
    {
        private bool _attached;
        public static void Initialize() { }
        public LongPressEffect()
        {
            _attached = false;

        }

        protected override void OnAttached()
        {
            Console.WriteLine("Invoking long click command...");
            //throw new NotImplementedException();
            if (!_attached) {
                if (Control != null)
                {
                    Control.LongClickable = true;
                    Control.LongClick += HandleLongClick;
                }
                _attached = true;
            }
        }

        private void HandleLongClick(object sender,Android.Views.View.LongClickEventArgs e) {
            Console.WriteLine("Invoking long click command...");
            var command = MyApp.Effects.LongPressEffect.getcommand(Element);
            command?.Execute(MyApp.Effects.LongPressEffect.Getcommandparameter(Element));

        }

        protected override void OnDetached()
        {
            //throw new NotImplementedException();
            if (_attached) {
                if (Control != null) {
                    Control.LongClickable = true;
                    Control.LongClick -= HandleLongClick;
                }
                _attached = false;
            }
        }

        protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
        {
            base.OnElementPropertyChanged(args);
        }
    }
}
conandx 回答:Xamarin.Android Tap手势和长按手势无法同时使用

这是Xamarin中的错误,here

作为解决方法,我使用了图像按钮,我的XAML现在看起来像这样:

<ImageButton x:Name="TapRight" Grid.Row="4" Grid.Column="2" Source="right64" 
       IsEnabled="{Binding RightEnabled}"
       Opacity="{Binding RightEnabled,Converter={StaticResource OpacityConverter}}"     
       effects:LongPressEffect.Command="{Binding LongPressGestureCommand}"
       effects:LongPressEffect.CommandParameter="{x:Static common:NavType.Right}"
        Command="{Binding TapGestureNavCommand}"
        CommandParameter="{x:Static common:NavType.Right}">
     <ImageButton.Effects>
         <effects:LongPressEffect></effects:LongPressEffect>
     </ImageButton.Effects>
</ImageButton>
本文链接:https://www.f2er.com/3164977.html

大家都在问