首页 文章

Xamarin表单向左滑动/向右滑动手势

提问于
浏览
24

我想通过说我对移动开发,Xamarin,C#, . Net完全陌生而言 .

我正在努力使用Xamarain Forms创建一个移动应用程序,并且遇到了无法使用滑动手势的问题,至少根据我看到的文档 .

我找到了这个网站:http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/

这描述了如何为IOS / Android添加一些额外的手势,以便在表单的上下文中访问 . 在我尝试遵循这一点之前,我想看看是否有其他人已经在Xamarin Forms应用程序中实现了滑动以及它们是如何实现的 .

我的目标是必须有一个水平堆栈布局 . 此布局包含7个按钮,每个按钮反映当前一周的一天 . 在堆栈布局上向左滑动会将按钮的文本更改为上一周 . 向右滑动会将按钮的文本更改为下周 .

所以我也尝试使用MVVM和XAML . 那么我可以分开向左滑动和向右滑动动作吗?我想使用ICommand根据滑动的方向将某个参数传递给函数 .

任何这个或任何建议的例子将不胜感激 .

6 回答

  • 1

    基于@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));
    }
    

    缺点是,只有在执行滑动后才能执行任何操作 .

  • 6

    如果您使用Xamarin Forms,那么这是一个很好的可能性),MR.Gestures支持所有Xamarin.Forms视图上的所有触摸手势 . 我成功地使用它并且非常满意它 . 它的成本非常合理10欧元,并且具有出色的文档 .

    如果您在Xamarin Forms中支持,请考虑投票this suggestion at UserVoice .

  • 1

    不需要第三方库..无需支付..只需添加这两个类并实现您的滑动监听器

    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 < 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);
    }
    }
    

    Step 2: From your Xamarin forms pass the view & also interface obj. Then you get result

    在我的情况下,我通过了标签

    SwipeListener swipeListener = new SwipeListener(lbl_swipe, this);
    

    Step 3: Implement the ISwipeCallBack interface

    public partial class SwipeLibPage : ContentPage, ISwipeCallBack
    

    示例项目 - > https://github.com/rranjithkumar100/Xamarin-Swipe-Library

  • 25

    您可以随时查看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;
    
  • 0

    也许这可以帮助某人 .

    我遇到了一个问题:有一个带有scrollview和grid的ContentPage . 我需要做的就是处理向左/向右滑动手势 . 在搜索了google / stackoverflow / github之后,我找到了一个名为XamarinFormsGestures的Nuget包 . 这对我帮助很大 . 所有指令都在链接内 . 有我的代码:

    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.
    
  • 10

    您可以使用Vapolia的NuGet包"XamarinFormsGesture"(doc available here) . 它免费且易于使用 .

    可在iOS和Android上使用,但它仅适用于物理设备(不适用于模拟器) .

相关问题