Я реализую жест смахивания для StackLayout (Listview внутри этого StackLayout), используя CustomRenderer в формах Xamarin. Прекрасно работает в iOS, но не работает в Android в разделе списка.
Размах работает за пределами ListView, но не работает в Listview. Я хочу, чтобы Gesture OnFling запускался при прокрутке в любом месте страницы.
Я ссылался на ссылку
https://arteksoftware.com/gesture-recognizers-with-xamarin-forms/
Вот мой код:
Xaml.cs
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SwipeApp1"
x:Class="SwipeApp1.MainPage">
<local:FancyStackLayout BackgroundColor="Pink">
<Grid>
<Grid.RowSpacing>0</Grid.RowSpacing>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="Welcome to Xamarin.Forms!"
VerticalOptions="Center"
HorizontalOptions="Center"
TextColor="Blue"/>
<ListView x:Name="lstContatos" HasUnevenRows="True" BackgroundColor="LightSkyBlue">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="{Binding userId}"></Label>
<Label Grid.Column="1" Text="{Binding id}"></Label>
<Label Grid.Column="2" Text="{Binding title}"></Label>
<Label Grid.Column="3" Text="{Binding body}"></Label>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</local:FancyLabel>
</ContentPage>
CustomRenderer.cs в проекте Droid
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using SwipeApp1;
using SwipeApp1.Droid;
using Android.Views;
//[assembly: ExportRenderer(typeof(GradientStackLayout),
typeof(GradientStackLayoutRenderer))]
[assembly: ExportRenderer (typeof(FancyStackLayout),
typeof(FancyAndroidLabelRenderer))]
namespace SwipeApp1.Droid
{
public class FancyAndroidLabelRenderer :
Xamarin.Forms.Platform.Android.VisualElementRenderer<StackLayout>
{
private readonly FancyGestureListener _listener;
private readonly GestureDetector _detector;
public FancyAndroidLabelRenderer ()
{
_listener = new FancyGestureListener ();
_detector = new GestureDetector (_listener);
}
protected override void OnElementChanged
(ElementChangedEventArgs<StackLayout> e)
{
base.OnElementChanged (e);
if (e.NewElement == null) {
this.GenericMotion -= HandleGenericMotion;
this.Touch -= HandleTouch;
}
if (e.OldElement == null) {
this.GenericMotion += HandleGenericMotion;
this.Touch += HandleTouch;
}
}
void HandleTouch (object sender, TouchEventArgs e)
{
_detector.OnTouchEvent (e.Event);
}
void HandleGenericMotion (object sender, GenericMotionEventArgs e)
{
_detector.OnTouchEvent (e.Event);
}
}
}
GestureListner.cs
using Android.Views;
using System;
namespace SwipeApp1.Droid
{
public class FancyGestureListener :
GestureDetector.SimpleOnGestureListener
{
public override bool OnContextClick(MotionEvent e)
{
return base.OnContextClick(e);
}
public override void OnLongPress (MotionEvent e)
{
Console.WriteLine ("OnLongPress");
base.OnLongPress (e);
}
public override bool OnDoubleTap (MotionEvent e)
{
Console.WriteLine ("OnDoubleTap");
return base.OnDoubleTap (e);
}
public override bool OnDoubleTapEvent (MotionEvent e)
{
Console.WriteLine ("OnDoubleTapEvent");
return base.OnDoubleTapEvent (e);
}
public override bool OnSingleTapUp (MotionEvent e)
{
Console.WriteLine ("OnSingleTapUp");
return base.OnSingleTapUp (e);
}
public override bool OnDown (MotionEvent e)
{
Console.WriteLine ("OnDown");
return base.OnDown (e);
}
private static int SWIPE_THRESHOLD = 100;
private static int SWIPE_VELOCITY_THRESHOLD = 100;
public override bool OnFling (MotionEvent e1, MotionEvent e2, float
velocityX, float velocityY)
{
//Console.WriteLine ("OnFling");
//return base.OnFling (e1, e2, velocityX, velocityY);
bool result = false;
try
{
float diffY = e2.GetY() - e1.GetY();
float diffX = e2.GetX() - e1.GetX();
if (Math.Abs(diffX) > Math.Abs(diffY))
{
if (Math.Abs(diffX) > SWIPE_THRESHOLD &&
Math.Abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffX > 0)
{
onSwipeRight();
}
else
{
onSwipeLeft();
}
result = true;
}
}
else if (Math.Abs(diffY) > SWIPE_THRESHOLD &&
Math.Abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffY > 0)
{
onSwipeBottom();
}
else
{
onSwipeTop();
}
result = true;
}
}
catch (Exception exception)
{
//exception.printStackTrace();
}
return result;
}
public override bool OnScroll (MotionEvent e1, MotionEvent e2, float
distanceX, float distanceY)
{
Console.WriteLine ("OnScroll");
return base.OnScroll (e1, e2, distanceX, distanceY);
}
public override void OnShowPress (MotionEvent e)
{
Console.WriteLine ("OnShowPress");
base.OnShowPress (e);
}
public override bool OnSingleTapConfirmed (MotionEvent e)
{
Console.WriteLine ("OnSingleTapConfirmed");
return base.OnSingleTapConfirmed (e);
}
public void onSwipeRight()
{
}
public void onSwipeLeft()
{
}
public void onSwipeTop()
{
}
public void onSwipeBottom()
{
}
}
}
Что мне нужно сделать, чтобы получить желаемый результат?