可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to preface this by saying I'm completely new to mobile development, Xamarin, C#, .Net.
I'm working on creating a mobile app using Xamarain Forms and have run into the problem of not having the swipe gesture available to me, at least according to the documentation I've seen.
I found this site: http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/
This describes how to add some additional gestures for IOS/Android to be accessible in the context of the form. Before I try to follow this, I wanted to see if anyone else has implemented swipe in a Xamarin Forms app and how they went about it.
My goals are that there has to be a horizontal stack layout. This layout contains 7 buttons, each button reflects a day in the current week. Swiping left on the stack layout will change the button's text to the previous week. Swiping right will change the button's text to the next week.
So I'm also trying to use MVVM for this and XAML. So is it possible for me to separate the swipe left and the swipe right action? I want to use ICommand to pass a certain parameter to a function based on the direction of the swipe.
Any examples of this or any advice would be greatly appreciated.
回答1:
If you're comfortable with paying for a third-party library (and you're using Xamarin Forms, so that's a good possibility), MR.Gestures
If you're one of the many people who are disappointed that touch gestures aren't supported in Xamarin Forms, consider voting for this suggestion at UserVoice.
回答2:
No need third party libraries.. No need to pay.. Just add these two classes & Implement your swipe listeners
Step 1: Copy paste these two classes
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 Math.Abs(translatedY)) { mISwipeCallback.onLeftSwipe(Content); } else if (translatedX > 0 && translatedX > Math.Abs(translatedY)) { mISwipeCallback.onRightSwipe(Content); } else if (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); } }
Step 2: From your Xamarin forms pass the view & also interface obj. Then you get result
In my case I pass the label
SwipeListener swipeListener = new SwipeListener(lbl_swipe, this);
Step 3: Implement the ISwipeCallBack interface
public partial class SwipeLibPage : ContentPage, ISwipeCallBack
Sample project --> https://github.com/rranjithkumar100/Xamarin-Swipe-Library
回答3:
You can always have a look at this simple demo. And use it as follows:
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;
回答4:
You can use the NuGet package "XamarinFormsGesture" of Vapolia (doc available here). It's free and easy to use.
Available on iOS and Android but it only works on physical devices (not on simulator).
回答5:
Building off of @Ranjith Kumar's solution, I came up with the following:
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 Math.Abs(_totalY)) { OnSwipedLeft(_totalX, _totalY); } else if (_totalX > 0 && _totalX > Math.Abs(_totalY)) { OnSwipedRight(_totalX, _totalY); } else if (_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)); }
The downside is you can't do anything while the swipe is performed, only after.