c# - 为什么 CollectionView 会阻止 SwipeGestureRecognizer?
问题描述
我有一个内容视图,我想在用户向下滑动时执行操作。据我所知,collectionview 会阻止它。因为如果我评论 collectionview 我的操作有效
<ContentView.Content>
<controls:CustomFrame CornerRadius="25,25,0,0" Margin="0" Padding="10" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout>
<StackLayout.GestureRecognizers>
<SwipeGestureRecognizer Direction="Down" Swiped="OnSwiped"/>
</StackLayout.GestureRecognizers>
<CollectionView ItemsSource="{Binding MyPins}" x:Name="ListPlaces"
SelectionMode="None">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" ItemSpacing="10"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame HasShadow="True" HorizontalOptions="FillAndExpand" BorderColor="#E5E5E5" CornerRadius="10" VerticalOptions="Start">
<StackLayout Orientation="Vertical">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding .}" Command="{Binding BindingContext.CallPlace, Source={x:Reference ListPlaces}}" ></TapGestureRecognizer>
</StackLayout.GestureRecognizers>
<Label x:Name="NameOfPlace" Text="{Binding Name}" TextColor="#2D78FD" FontSize="14" FontFamily="Robobo"/>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</controls:CustomFrame>
</ContentView.Content>
解决方案
您可以使用自定义渲染器来实现它
在表格中
创建自定义 CollectionView
public class MyCollectionView:CollectionView
{
public event EventHandler SwipeDown;
public event EventHandler SwipeUp;
public void OnSwipeDown() =>
SwipeDown?.Invoke(this, null);
public void OnSwipeUp() =>
SwipeUp?.Invoke(this, null);
}
在安卓项目中
using Android.Content;
using Android.Views;
using App1;
using App1.Droid;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyCollectionView), typeof(MyCollectionViewRenderer))]
namespace App1.Droid
{
public class MyCollectionViewRenderer : CollectionViewRenderer
{
readonly CustomGestureListener _listener;
readonly GestureDetector _detector;
public MyCollectionViewRenderer(Context context) : base(context)
{
_listener = new CustomGestureListener();
_detector = new GestureDetector(context, _listener);
}
public override bool DispatchTouchEvent(MotionEvent e)
{
if (_detector != null)
{
_detector.OnTouchEvent(e);
base.DispatchTouchEvent(e);
return true;
}
return base.DispatchTouchEvent(e);
}
public override bool OnTouchEvent(MotionEvent ev)
{
base.OnTouchEvent(ev);
if (_detector != null)
return _detector.OnTouchEvent(ev);
return false;
}
protected override void OnElementChanged(ElementChangedEventArgs<ItemsView> elementChangedEvent)
{
base.OnElementChanged(elementChangedEvent);
if (elementChangedEvent.NewElement == null)
{
_listener.OnSwipeDown -= HandleOnSwipeDown;
_listener.OnSwipeUp -= HandleOnSwipeUp;
}
if (elementChangedEvent.OldElement == null)
{
_listener.OnSwipeDown += HandleOnSwipeDown;
_listener.OnSwipeUp += HandleOnSwipeUp;
}
void HandleOnSwipeDown(object sender, EventArgs e) =>
((MyCollectionView)Element).OnSwipeDown();
void HandleOnSwipeUp(object sender, EventArgs e) =>
((MyCollectionView)Element).OnSwipeUp();
}
}
public class CustomGestureListener : GestureDetector.SimpleOnGestureListener
{
static readonly int SWIPE_THRESHOLD = 100;
static readonly int SWIPE_VELOCITY_THRESHOLD = 100;
MotionEvent mLastOnDownEvent;
public event EventHandler OnSwipeDown;
public event EventHandler OnSwipeUp;
public override bool OnDown(MotionEvent e)
{
mLastOnDownEvent = e;
return true;
}
public override bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
if (e1 == null)
e1 = mLastOnDownEvent;
float diffY = e2.GetY() - e1.GetY();
float diffX = e2.GetX() - e1.GetX();
if (Math.Abs(diffY) > Math.Abs(diffX))
{
if (Math.Abs(diffY) > SWIPE_THRESHOLD && Math.Abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffY > 0)
OnSwipeUp?.Invoke(this, null);
else
OnSwipeDown?.Invoke(this, null);
}
}
return base.OnFling(e1, e2, velocityX, velocityY);
}
}
}
在xml中
现在您可以像访问它一样
<StackLayout>
<local:MyCollectionView SwipeDown="MyCollectionView_SwipeDown" SwipeUp="MyCollectionView_SwipeUp" >
//...
</local:MyCollectionView>
</StackLayout>
推荐阅读
- c# - 如何在 ASP.NET Core 中的(有吸引力的报告)Fastreport.NET 中设置指向当前请求路径的超链接
- sql - 删除具有连接到其他表的主键的重复行
- python - Fillna 基于另一列
- java - Java ) 选择人们无法输入的令牌或其他想法来解决这个问题
- python - 如何导入 pandas_datareader
- postgresql - Pyspark:“ImportError:无法导入名称'st_makePoint'
- angular - 无法将数组与 ngModel 以角度方式绑定,因为索引是只读的
- intellij-idea - JetBrains GoLand 找不到包 2020.2
- ms-access - “无法打开 SQL 服务器”错误——但使用 Access?
- c++ - 为什么在这种情况下 seekp() 失败?