![](/img/trans.png)
[英]How to handle triple (or configured numbers) of tap gesture on Xamarin.Android?
[英]Xamarin.Android Tap Gesture and Long Press Gesture not working together
我通過子類RoutingEffect
創建了一個自定義效果,以便在我的 Xamarin 項目中允許LongPressGesture
和iOS
的Android
。
我在共享項目的XAML
中的Image
上使用此效果,並且此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
(當我點擊和長按圖像時,我得到單獨的功能),但是對於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),
typeof(LongPressEffect),
(object)null,
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 oldValue, 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);
}
}
}
這是 Xamarin 中的一個錯誤,更多細節可以在這里找到
作為一種解決方法,我使用了 ImageButton 或 Android 和 Image for IOS 並使可見性平台依賴。 我的 XAML 現在看起來像這樣:
<ImageButton x:Name="Tap" 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.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean"
iOS="False"
Android="True"/>
</ImageButton.IsVisible>
<ImageButton.Effects>
<effects:LongPressEffect></effects:LongPressEffect>
</ImageButton.Effects>
</ImageButton>
<!--Due to different behaviour on platform(s) different views were needed for different platforms.-->
<Image x:Name="TapIOS" 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}">
<Image.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean"
iOS="True"
Android="False"/>
</Image.IsVisible>
<Image.GestureRecognizers>
<TapGestureRecognizer
NumberOfTapsRequired="1"
Command="{Binding TapGestureNavCommand}"
CommandParameter="{x:Static common:NavType.Right}"/>
</Image.GestureRecognizers>
<Image.Effects>
<effects:LongPressEffect></effects:LongPressEffect>
</Image.Effects>
</Image>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.