在 Xamarin.Form 下扩展手势

 手势基础(Android & iOS)

> Andorid手势基础

当用户触摸屏幕时会产生很多的触摸事件,down、up、move等等。View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,如下:

[java] view plain copy

print?

public class MainActivity extends Activity {  

...  

// This example shows an Activity, but you would use the same approach if  

// you were subclassing a View.  

@Override  

public boolean onTouchEvent(MotionEvent event){   

          

    int action = MotionEventCompat.getActionMasked(event);  

          

    switch(action) {  

        case (MotionEvent.ACTION_DOWN) :  

            Log.d(DEBUG_TAG,"Action was DOWN");  

            return true;  

        case (MotionEvent.ACTION_MOVE) :  

            Log.d(DEBUG_TAG,"Action was MOVE");  

            return true;  

        case (MotionEvent.ACTION_UP) :  

            Log.d(DEBUG_TAG,"Action was UP");  

            return true;  

        case (MotionEvent.ACTION_CANCEL) :  

            Log.d(DEBUG_TAG,"Action was CANCEL");  

            return true;  

        case (MotionEvent.ACTION_OUTSIDE) :  

            Log.d(DEBUG_TAG,"Movement occurred outside bounds " +  

                    "of current screen element");  

            return true;        

        default :   

            return super.onTouchEvent(event);  

    }        

}  

    OnTouch提供的事件还是相对较简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦,因为我们要根据用户触摸的轨迹去判断是什么手势。Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势。

 

public class GestureDetector extends Object    

Java.lang.Object

android.view.GestureDetector

 

  GestureDetector属于android.view包,android还提供了android.gesture包支持更多的手势操作,以后我们会介绍到。官方的介绍中使用了GestureDetectorCompat处理手势识别,为什么使用GestureDetectorCompat替换了GestureDetector呢,官方的是这样解释的:

https://img-blog.csdn.net/20131121153739828

 

 GestureDetectorCompat实例化有下面两种方法:

https://img-blog.csdn.net/20131121154752046

 

GestureDetector

GestureDetector类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener;SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,它实现了上述两个接口,该类是static class,也就是说它实际上是一个外部类,我们可以在外部继承这个类,重写里面的手势处理方法。因此实现手势识别有两种方法,一种实现OnGestureListener接口,另一种是使用SimpleOnGestureListener类。

 

OnGestureListener有下面的几个动作:

按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。

抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。

长按(onLongPress): 手指按在持续一段时间,并且没有松开。

滚动(onScroll): 手指在触摸屏上滑动。

按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。

抬起(onSingleTapUp):手指离开触摸屏的那一刹那。

  使用OnGestureListener接口,这样需要重载OnGestureListener接口所有的方法,适合监听所有的手势,正如官方文档提到的“Detecing All Supported Gestures

 

>iOS 手势基础

UIGestureRecognize手势识别器的使用简介

手势识别器是一个抽象类, 特殊的触摸事件. 我们不使用它本身,而是使用它的子类

类型

类 名

平移

UIPanGestureRecognizer

轻扫(滑动)

UISwipeGestureRecognizer

长按

UILongPressGestureRecognizer

捏合

UIPinchGestureRecognizer

旋转

UIRotationGestureRecognizer

轻拍

UITapGestureRecognizer

 

 

 实战(ps:下面以自定义以为XF定义以随便一个手势为例:)

XF部分:

using System;

using Xamarin.Forms;

namespace KKMobile.Control

{

public class LongPressMaskingView : Xamarin.Forms.Grid

{

public event EventHandler LongPressActivated;

public event EventHandler LongPressEnd;

public event EventHandler TapUPed;

 

public LongPressMaskingView()

{

}

public void HandTapUped(object sender, EventArgs e)

{

Device.BeginInvokeOnMainThread(() =>

{

if (TapUPed != null)

{

TapUPed(this, new EventArgs());

}

});

}

public void HandleLongPress_End(object sender, EventArgs e)

{

Device.BeginInvokeOnMainThread(() =>

{

if (LongPressEnd != null)

{

LongPressEnd(this, new EventArgs());

}

});

}

public void HandleLongPress(object sender, EventArgs e)

{

Device.BeginInvokeOnMainThread(() =>

{

if (LongPressActivated != null)

{

System.Diagnostics.Debug.WriteLine("HandleLongPress");

LongPressActivated(this, new EventArgs());

}

});

}

 

#region 绑定手势

 

// public static readonly BindableProperty TappedCommandProperty =

//BindableProperty.Create(nameof(TappedCommand),

// typeof(ICommand),

// typeof(LongPressGerCachImage),

// default(ICommand));

 

// public ICommand TappedCommand

// {

// get { return (ICommand)GetValue(TappedCommandProperty); }

// set { SetValue(TappedCommandProperty, value); }

// }

 

// public static readonly BindableProperty LongPressCommandProperty =

// BindableProperty.Create(nameof(LongPressCommand),

// typeof(ICommand),

// typeof(LongPressGerCachImage),

// default(ICommand));

 

// public ICommand LongPressCommand

// {

// get { return (ICommand)GetValue(LongPressCommandProperty); }

// set { SetValue(LongPressCommandProperty, value); }

// }

 

// public LongPressGerCachImage() { }

#endregion

}

}

 

===============================================================================

 

Xamarin.iOS 实现

using System;

using Foundation;

using UIKit;

using Xamarin.Forms.Platform.iOS;

using Xamarin.Forms;

using KKMobile.Control;

using KKMobile.iOS.Renderer;

[assembly: ExportRenderer(typeof(LongPressMaskingView), typeof(LongPressMaskingViewRenderer))]

namespace KKMobile.iOS.Renderer

{

public class LongPressMaskingViewRenderer : ViewRenderer

{

LongPressMaskingView view;

UILongPressGestureRecognizer longPressGer { get; set; }

UITapGestureRecognizer TapGer { get; set; }

public LongPressMaskingViewRenderer()

{

longPressGer = new UILongPressGestureRecognizer((longPress) =>

{

if (longPress.State == UIGestureRecognizerState.Began)

{

view.HandleLongPress(view, new EventArgs());

}

if (longPress.State == UIGestureRecognizerState.Ended)

{

view.HandleLongPress_End(view, new EventArgs());

}

})

{ MinimumPressDuration = 0.5, NumberOfTouchesRequired = 1 };

//**

TapGer = new UITapGestureRecognizer((Tap) =>

{

if (Tap.State == UIGestureRecognizerState.Ended)

{

view.HandTapUped(view,new EventArgs());

}

}) { };

 

this.AddGestureRecognizer(TapGer);

this.AddGestureRecognizer(longPressGer);

}

protected override void OnElementChanged(ElementChangedEventArgs e)

{

base.OnElementChanged(e);

if (e.NewElement != null)

{

view = e.NewElement as LongPressMaskingView;

}

 

if (e.NewElement == null)

{

if (longPressGer != null)

{

this.RemoveGestureRecognizer(longPressGer);

}

}

 

if (e.OldElement == null)

{

this.AddGestureRecognizer(longPressGer);

}

}

 

//UITapGestureRecognizer tapGesturesRecognizer;

//UILongPressGestureRecognizer longPressGesturesRecognizer;

//protected override void OnElementChanged(ElementChangedEventArgs e)

//{

// base.OnElementChanged(e);

 

// tapGesturesRecognizer = new UITapGestureRecognizer(() =>

// {

// var grid = (LongPressGerCachImage)Element;

// if (grid.TappedCommand.CanExecute(Element.BindingContext))

// {

// grid.TappedCommand.Execute(Element.BindingContext);

// }

// });

 

// longPressGesturesRecognizer = new UILongPressGestureRecognizer(() =>

// {

// var grid = (LongPressGerCachImage)Element;

// if (longPressGesturesRecognizer.State == UIGestureRecognizerState.Ended &&

// grid.LongPressCommand.CanExecute(Element.BindingContext))

// {

// grid.LongPressCommand.Execute(Element.BindingContext);

// }

// });

 

// this.RemoveGestureRecognizer(tapGesturesRecognizer);

// this.RemoveGestureRecognizer(longPressGesturesRecognizer);

 

// this.AddGestureRecognizer(tapGesturesRecognizer);

// this.AddGestureRecognizer(longPressGesturesRecognizer);

//}

}

}

 

 

-----------

 

===============================================================================

Xamarin.Android实现

一》先建立一个手势事件监听类

sing System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Android.App;

using Android.Content;

using Android.OS;

using Android.Runtime;

using Android.Views;

using Android.Widget;

 

namespace KKMobile.Droid.Renderer

{

public class FancyGestureListener : GestureDetector.SimpleOnGestureListener

{

public event EventHandler HandTapUped;

public override bool OnSingleTapUp(MotionEvent e) //抬起(onSingleTapUp):手指离开触 摸屏的那一刹那。

{

HandTapUped(this, null);

return true;

}

}

}

 

 

二》建立安卓手势Render类

using Xamarin.Forms.Platform.Android;

using Xamarin.Forms;

using Android.Views;

using KKMobile.Droid.Renderer;

using KKMobile.Control;

using System;

 

[assembly: ExportRenderer(typeof(LongPressMaskingView), typeof(LongPressMaskingViewRenderer_Droid))]

namespace KKMobile.Droid.Renderer

{

public class LongPressMaskingViewRenderer_Droid : ViewRenderer

{

LongPressMaskingView _longPressMaskingView;

 

private readonly FancyGestureListener _listener;

private readonly GestureDetector _detector;

 

public LongPressMaskingViewRenderer_Droid()

{

_listener = new FancyGestureListener();

_detector = new GestureDetector(_listener);

}

protected override void OnElementChanged(ElementChangedEventArgs e)

{

base.OnElementChanged(e);

 

if (e.NewElement != null)

{

_longPressMaskingView = e.NewElement as LongPressMaskingView;

}

if (e.NewElement == null)

{

this.GenericMotion -= HandleGenericMotion;

this.Touch -= HandleTouch;

//_listener.HandleLongPress -= OnHandLongPress;

//_listener.HandLongPressEnded -= OnHandLongPressEnded;

_listener.HandTapUped -= OnHandTapUped;

}

if (e.OldElement == null)

{

this.GenericMotion += HandleGenericMotion;

this.Touch += HandleTouch;

//_listener.HandleLongPress += OnHandLongPress;

//_listener.HandLongPressEnded += OnHandLongPressEnded;

_listener.HandTapUped += OnHandTapUped;

}

}

void HandleTouch(object sender, TouchEventArgs e)

{

Console.WriteLine("====="+e.Event.Action);

try

{

_longPressMaskingView = this.Element as LongPressMaskingView;

if (e.Event.Action == MotionEventActions.Down)

{

Console.WriteLine(e.Event.Action);

_longPressMaskingView.HandleLongPress(this, new System.EventArgs());

Console.WriteLine("--down--");

}

if (e.Event.Action == MotionEventActions.Up || e.Event.Action == MotionEventActions.Cancel)

{

 

Console.WriteLine(e.Event.Action);

_longPressMaskingView.HandleLongPress_End(this, new System.EventArgs());

Console.WriteLine("--up--");

}

_detector.OnTouchEvent(e.Event);

}

catch (Exception ex) {

 

}

}

 

void HandleGenericMotion(object sender, GenericMotionEventArgs e)

{

_detector.OnTouchEvent(e.Event);

}

 

void OnHandTapUped(object sender, EventArgs e)

{

_longPressMaskingView = this.Element as LongPressMaskingView;

_longPressMaskingView.HandTapUped(this, new System.EventArgs());

}

}

}

 

结语

做到这里呢,我们就简单的实现了Xamarin下的一个手势的扩展。在使用功能的同时,可能还会遇到手势冲突等问题哈,我们会再接下来的博文继续探究手势这块的知识。

 

你可能感兴趣的:(Xamarin实战进阶)