Xamarin 表单滑动 Left/Swipe 向右手势
Xamarin Forms Swipe Left/Swipe Right Gestures
首先我想说我是移动开发、Xamarin、C#、.Net 的新手。
我正在使用 Xamarain Forms 创建一个移动应用程序,并且 运行 遇到了我无法使用滑动手势的问题,至少根据我看到的文档是这样。
我找到了这个网站:http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/
这描述了如何为 IOS/Android 添加一些额外的手势以便在表单的上下文中访问。在尝试进行此操作之前,我想看看是否还有其他人在 Xamarin Forms 应用程序中实现了滑动,以及他们是如何实现的。
我的目标是必须有水平堆栈布局。此布局包含 7 个按钮,每个按钮反映当前一周中的一天。在堆栈布局上向左滑动会将按钮的文本更改为上周。向右滑动会将按钮的文本更改为下周。
所以我也在尝试为此使用 MVVM XAML。那么我可以将向左滑动和向右滑动的动作分开吗?我想使用ICommand根据滑动的方向将某个参数传递给一个函数
如有任何此类示例或任何建议,我们将不胜感激。
您可以随时查看 this 简单演示。并按如下方式使用它:
GestureFrame gi = new GestureFrame
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.FromHex("bf3122"),
};
gi.SwipeDown += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Down Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Down Detected");
};
gi.SwipeTop += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Top Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Top Detected");
};
gi.SwipeLeft += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Left Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Left Detected");
};
gi.SwipeRight += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Right Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Right Detected");
};
this.Content = gi;
不需要第三方库..不需要付费..只需添加这两个 类 并实现您的滑动监听器
第一步:复制粘贴这两个类
SwipeListener.cs
using System;
using Xamarin.Forms;
namespace SwipeLib
{
public class SwipeListener : PanGestureRecognizer
{
private ISwipeCallBack mISwipeCallback;
private double translatedX = 0, translatedY = 0;
public SwipeListener(View view, ISwipeCallBack iSwipeCallBack)
{
mISwipeCallback = iSwipeCallBack;
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += OnPanUpdated;
view.GestureRecognizers.Add(panGesture);
}
void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
View Content = (View)sender;
switch (e.StatusType) {
case GestureStatus.Running:
try {
translatedX = e.TotalX;
translatedY = e.TotalY;
} catch (Exception err) {
System.Diagnostics.Debug.WriteLine("" + err.Message);
}
break;
case GestureStatus.Completed:
System.Diagnostics.Debug.WriteLine("translatedX : " + translatedX);
System.Diagnostics.Debug.WriteLine("translatedY : " + translatedY);
if (translatedX < 0 && Math.Abs(translatedX) > Math.Abs(translatedY)) {
mISwipeCallback.onLeftSwipe(Content);
} else if (translatedX > 0 && translatedX > Math.Abs(translatedY)) {
mISwipeCallback.onRightSwipe(Content);
} else if (translatedY < 0 && Math.Abs(translatedY) > Math.Abs(translatedX)) {
mISwipeCallback.onTopSwipe(Content);
} else if (translatedY > 0 && translatedY > Math.Abs(translatedX)) {
mISwipeCallback.onBottomSwipe(Content);
} else {
mISwipeCallback.onNothingSwiped(Content);
}
break;
}
}
}
}
ISwipeCallBack.cs
using System;
using Xamarin.Forms;
namespace SwipeLib
{
public interface ISwipeCallBack
{
void onLeftSwipe(View view);
void onRightSwipe(View view);
void onTopSwipe(View view);
void onBottomSwipe(View view);
void onNothingSwiped(View view);
}
}
第 2 步:从您的 Xamarin 表单传递视图和接口对象。然后你得到结果
在我的例子中,我传递了标签
SwipeListener swipeListener = new SwipeListener(lbl_swipe, this);
步骤 3:实现 ISwipeCallBack 接口
public partial class SwipeLibPage : ContentPage, ISwipeCallBack
示例项目 --> https://github.com/rranjithkumar100/Xamarin-Swipe-Library
基于@Ranjith Kumar 的解决方案,我得出了以下结论:
public delegate void SwipedEventHandler(ISwipeListener sender, SwipedEventArgs e);
public class SwipedEventArgs : EventArgs
{
readonly double _x;
public double X => _x;
readonly double _y;
public double Y => _y;
readonly View _view;
public View View => _view;
public SwipedEventArgs(View view, double x, double y)
{
_view = view;
_x = x;
_y = y;
}
}
public interface ISwipeListener
{
event SwipedEventHandler SwipedDown;
event SwipedEventHandler SwipedLeft;
event SwipedEventHandler SwipedNothing;
event SwipedEventHandler SwipedRight;
event SwipedEventHandler SwipedUp;
double TotalX
{
get;
}
double TotalY
{
get;
}
}
public class SwipeListener : PanGestureRecognizer, ISwipeListener
{
public event SwipedEventHandler SwipedDown;
public event SwipedEventHandler SwipedLeft;
public event SwipedEventHandler SwipedNothing;
public event SwipedEventHandler SwipedRight;
public event SwipedEventHandler SwipedUp;
double _totalX = 0, _totalY = 0;
public double TotalX => _totalX;
public double TotalY => _totalY;
readonly View _view;
public SwipeListener(View view) : base()
{
_view = view;
_view.GestureRecognizers.Add(this);
PanUpdated += OnPanUpdated;
}
void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
switch (e.StatusType)
{
case GestureStatus.Running:
try
{
_totalX = e.TotalX;
_totalY = e.TotalY;
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
}
break;
case GestureStatus.Completed:
if (_totalX < 0 && Math.Abs(_totalX) > Math.Abs(_totalY))
{
OnSwipedLeft(_totalX, _totalY);
}
else if (_totalX > 0 && _totalX > Math.Abs(_totalY))
{
OnSwipedRight(_totalX, _totalY);
}
else if (_totalY < 0 && Math.Abs(_totalY) > Math.Abs(_totalX))
{
OnSwipedUp(_totalX, _totalY);
}
else if (_totalY > 0 && _totalY > Math.Abs(_totalX))
{
OnSwipedDown(_totalX, _totalY);
}
else OnSwipedNothing(_totalX, _totalY);
break;
}
}
protected virtual void OnSwipedDown(double x, double y)
=> SwipedDown?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedLeft(double x, double y)
=> SwipedLeft?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedNothing(double x, double y)
=> SwipedNothing?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedRight(double x, double y)
=> SwipedRight?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedUp(double x, double y)
=> SwipedUp?.Invoke(this, new SwipedEventArgs(_view, x, y));
}
缺点是在执行滑动时你不能做任何事情,只能在之后。
也许这对某人有帮助。
我遇到了一个问题:里面有一个带有滚动视图和网格的 ContentPage。我需要做的就是处理滑动 left/right 手势。
通过 google/Whosebug/github 搜索后,我找到了一个名为 XamarinFormsGestures 的 Nuget 包。这对我帮助很大。所有指令都在link里面。
有我的代码:
Vapolia.Lib.Ui.Gesture.SetSwipeLeftCommand(scrollviewgrid,
new Command(() => { OnLeftSwipe(); })); // What's going on when left swiped.
Vapolia.Lib.Ui.Gesture.SetSwipeRightCommand(scrollviewgrid,
new Command(() => { OnRightSwipe(); })); // What's going on when right swiped.
Xamarin.Forms 引入了 SwipeGestureRecognizer :
<BoxView Color="Teal" ...>
<BoxView.GestureRecognizers>
<SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped"/>
</BoxView.GestureRecognizers>
</BoxView>
仅供参考
SwipeView 在 Xamarin.Forms 4.4 中可用。
SwipeViewclass还定义了四个事件:
SwipeStarted 在滑动开始时触发。伴随此事件的 SwipeStartedEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性。
SwipeChanging 在滑动移动时触发。
伴随此事件的 SwipeChangingEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性 和类型为 double 的 Offset 属性。
SwipeEnded 在滑动结束时触发。伴随此事件的 SwipeEndedEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性。
CloseRequested 在滑动项关闭时触发。
另外,SwipeView定义了一个Close方法,用于关闭滑动项。
有关 Xamarin Forms 一些新功能的更多信息,请访问此 link。
首先我想说我是移动开发、Xamarin、C#、.Net 的新手。
我正在使用 Xamarain Forms 创建一个移动应用程序,并且 运行 遇到了我无法使用滑动手势的问题,至少根据我看到的文档是这样。
我找到了这个网站:http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/
这描述了如何为 IOS/Android 添加一些额外的手势以便在表单的上下文中访问。在尝试进行此操作之前,我想看看是否还有其他人在 Xamarin Forms 应用程序中实现了滑动,以及他们是如何实现的。
我的目标是必须有水平堆栈布局。此布局包含 7 个按钮,每个按钮反映当前一周中的一天。在堆栈布局上向左滑动会将按钮的文本更改为上周。向右滑动会将按钮的文本更改为下周。
所以我也在尝试为此使用 MVVM XAML。那么我可以将向左滑动和向右滑动的动作分开吗?我想使用ICommand根据滑动的方向将某个参数传递给一个函数
如有任何此类示例或任何建议,我们将不胜感激。
您可以随时查看 this 简单演示。并按如下方式使用它:
GestureFrame gi = new GestureFrame
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.FromHex("bf3122"),
};
gi.SwipeDown += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Down Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Down Detected");
};
gi.SwipeTop += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Top Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Top Detected");
};
gi.SwipeLeft += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Left Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Left Detected");
};
gi.SwipeRight += (s, e) =>
{
DisplayAlert("Gesture Info", "Swipe Right Detected", "OK");
ViewModel.SampleCommand.Execute("Swipe Right Detected");
};
this.Content = gi;
不需要第三方库..不需要付费..只需添加这两个 类 并实现您的滑动监听器
第一步:复制粘贴这两个类
SwipeListener.cs
using System;
using Xamarin.Forms;
namespace SwipeLib
{
public class SwipeListener : PanGestureRecognizer
{
private ISwipeCallBack mISwipeCallback;
private double translatedX = 0, translatedY = 0;
public SwipeListener(View view, ISwipeCallBack iSwipeCallBack)
{
mISwipeCallback = iSwipeCallBack;
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += OnPanUpdated;
view.GestureRecognizers.Add(panGesture);
}
void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
View Content = (View)sender;
switch (e.StatusType) {
case GestureStatus.Running:
try {
translatedX = e.TotalX;
translatedY = e.TotalY;
} catch (Exception err) {
System.Diagnostics.Debug.WriteLine("" + err.Message);
}
break;
case GestureStatus.Completed:
System.Diagnostics.Debug.WriteLine("translatedX : " + translatedX);
System.Diagnostics.Debug.WriteLine("translatedY : " + translatedY);
if (translatedX < 0 && Math.Abs(translatedX) > Math.Abs(translatedY)) {
mISwipeCallback.onLeftSwipe(Content);
} else if (translatedX > 0 && translatedX > Math.Abs(translatedY)) {
mISwipeCallback.onRightSwipe(Content);
} else if (translatedY < 0 && Math.Abs(translatedY) > Math.Abs(translatedX)) {
mISwipeCallback.onTopSwipe(Content);
} else if (translatedY > 0 && translatedY > Math.Abs(translatedX)) {
mISwipeCallback.onBottomSwipe(Content);
} else {
mISwipeCallback.onNothingSwiped(Content);
}
break;
}
}
}
}
ISwipeCallBack.cs
using System;
using Xamarin.Forms;
namespace SwipeLib
{
public interface ISwipeCallBack
{
void onLeftSwipe(View view);
void onRightSwipe(View view);
void onTopSwipe(View view);
void onBottomSwipe(View view);
void onNothingSwiped(View view);
}
}
第 2 步:从您的 Xamarin 表单传递视图和接口对象。然后你得到结果
在我的例子中,我传递了标签
SwipeListener swipeListener = new SwipeListener(lbl_swipe, this);
步骤 3:实现 ISwipeCallBack 接口
public partial class SwipeLibPage : ContentPage, ISwipeCallBack
示例项目 --> https://github.com/rranjithkumar100/Xamarin-Swipe-Library
基于@Ranjith Kumar 的解决方案,我得出了以下结论:
public delegate void SwipedEventHandler(ISwipeListener sender, SwipedEventArgs e);
public class SwipedEventArgs : EventArgs
{
readonly double _x;
public double X => _x;
readonly double _y;
public double Y => _y;
readonly View _view;
public View View => _view;
public SwipedEventArgs(View view, double x, double y)
{
_view = view;
_x = x;
_y = y;
}
}
public interface ISwipeListener
{
event SwipedEventHandler SwipedDown;
event SwipedEventHandler SwipedLeft;
event SwipedEventHandler SwipedNothing;
event SwipedEventHandler SwipedRight;
event SwipedEventHandler SwipedUp;
double TotalX
{
get;
}
double TotalY
{
get;
}
}
public class SwipeListener : PanGestureRecognizer, ISwipeListener
{
public event SwipedEventHandler SwipedDown;
public event SwipedEventHandler SwipedLeft;
public event SwipedEventHandler SwipedNothing;
public event SwipedEventHandler SwipedRight;
public event SwipedEventHandler SwipedUp;
double _totalX = 0, _totalY = 0;
public double TotalX => _totalX;
public double TotalY => _totalY;
readonly View _view;
public SwipeListener(View view) : base()
{
_view = view;
_view.GestureRecognizers.Add(this);
PanUpdated += OnPanUpdated;
}
void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
switch (e.StatusType)
{
case GestureStatus.Running:
try
{
_totalX = e.TotalX;
_totalY = e.TotalY;
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
}
break;
case GestureStatus.Completed:
if (_totalX < 0 && Math.Abs(_totalX) > Math.Abs(_totalY))
{
OnSwipedLeft(_totalX, _totalY);
}
else if (_totalX > 0 && _totalX > Math.Abs(_totalY))
{
OnSwipedRight(_totalX, _totalY);
}
else if (_totalY < 0 && Math.Abs(_totalY) > Math.Abs(_totalX))
{
OnSwipedUp(_totalX, _totalY);
}
else if (_totalY > 0 && _totalY > Math.Abs(_totalX))
{
OnSwipedDown(_totalX, _totalY);
}
else OnSwipedNothing(_totalX, _totalY);
break;
}
}
protected virtual void OnSwipedDown(double x, double y)
=> SwipedDown?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedLeft(double x, double y)
=> SwipedLeft?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedNothing(double x, double y)
=> SwipedNothing?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedRight(double x, double y)
=> SwipedRight?.Invoke(this, new SwipedEventArgs(_view, x, y));
protected virtual void OnSwipedUp(double x, double y)
=> SwipedUp?.Invoke(this, new SwipedEventArgs(_view, x, y));
}
缺点是在执行滑动时你不能做任何事情,只能在之后。
也许这对某人有帮助。
我遇到了一个问题:里面有一个带有滚动视图和网格的 ContentPage。我需要做的就是处理滑动 left/right 手势。 通过 google/Whosebug/github 搜索后,我找到了一个名为 XamarinFormsGestures 的 Nuget 包。这对我帮助很大。所有指令都在link里面。 有我的代码:
Vapolia.Lib.Ui.Gesture.SetSwipeLeftCommand(scrollviewgrid,
new Command(() => { OnLeftSwipe(); })); // What's going on when left swiped.
Vapolia.Lib.Ui.Gesture.SetSwipeRightCommand(scrollviewgrid,
new Command(() => { OnRightSwipe(); })); // What's going on when right swiped.
Xamarin.Forms 引入了 SwipeGestureRecognizer :
<BoxView Color="Teal" ...>
<BoxView.GestureRecognizers>
<SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped"/>
</BoxView.GestureRecognizers>
</BoxView>
仅供参考
SwipeView 在 Xamarin.Forms 4.4 中可用。
SwipeViewclass还定义了四个事件:
SwipeStarted 在滑动开始时触发。伴随此事件的 SwipeStartedEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性。
SwipeChanging 在滑动移动时触发。 伴随此事件的 SwipeChangingEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性 和类型为 double 的 Offset 属性。
SwipeEnded 在滑动结束时触发。伴随此事件的 SwipeEndedEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性。
CloseRequested 在滑动项关闭时触发。 另外,SwipeView定义了一个Close方法,用于关闭滑动项。
有关 Xamarin Forms 一些新功能的更多信息,请访问此 link。