我编写了一个Android自定义渲染器来处理触摸事件。我能够成功处理MotionEventActions.Down事件,但在渲染器中未调用其他事件。
我正在尝试同时处理MotionEventActions.Down和MotionEventActions.Up。
如何获取要调用的MotionEventActions.Up事件?
渲染器:
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using SecurityCompanyApp;
using SecurityCompanyApp.Droid.Renderers;
using System;
#pragma warning disable CS0612 // Type or member is obsolete
[assembly: ExportRenderer(typeof(TouchView), typeof(TouchViewRenderer))]
#pragma warning restore CS0612 // Type or member is obsolete
namespace SecurityCompanyApp.Droid.Renderers
{
[Obsolete]
public class TouchViewRenderer : ViewRenderer
{
bool isTouchedDown = false;
public override bool OnTouchEvent(MotionEvent e)
{
var touchView = Element as TouchView;
switch (e.Action)
{
case MotionEventActions.Down:
HandleTouchDown(touchView);
break;
case MotionEventActions.Up:
HandleTouchUp(touchView);
break;
default:
isTouchedDown = false;
break;
}
return base.OnTouchEvent(e);
}
private void HandleTouchUp(TouchView touchView)
{
isTouchedDown = false;
touchView.TouchEnded();
}
private void HandleTouchDown(TouchView touchView)
{
if (!isTouchedDown)
{
touchView.TouchStarted();
}
isTouchedDown = true;
}
public override bool OnInterceptTouchEvent(MotionEvent e)
{
BringToFront();
return true;
}
}
}
Xamarin.Forms.View:
using System;
using System.Threading;
using Xamarin.Forms;
namespace SecurityCompanyApp
{
public partial class TouchView : ContentView
{
public event EventHandler TouchStart = delegate { };
public event EventHandler TouchEnd = delegate { };
public static readonly BindableProperty IsTouchingProperty = BindableProperty.Create(
nameof(IsTouching),
typeof(bool),
typeof(TouchView),
false);
public bool IsTouching
{
get => (bool)GetValue(IsTouchingProperty);
set => SetValue(IsTouchingProperty, value);
}
public static readonly BindableProperty TouchDurationProperty = BindableProperty.Create(
nameof(TouchDuration),
typeof(TimeSpan),
typeof(TouchView),
TimeSpan.Zero);
public TimeSpan TouchDuration
{
get => (TimeSpan)GetValue(TouchDurationProperty);
set => SetValue(TouchDurationProperty, value);
}
public static readonly BindableProperty MaxTouchDurationProperty = BindableProperty.Create(
nameof(MaxTouchDuration),
typeof(double),
typeof(TouchView),
10.0);
public double MaxTouchDuration
{
get => (double)(GetValue(MaxTouchDurationProperty));
set => SetValue(MaxTouchDurationProperty, value);
}
public static readonly BindableProperty TouchStartTimeProperty = BindableProperty.Create(
nameof(TouchStartTime),
typeof(DateTime),
typeof(TouchView),
new DateTime());
public DateTime TouchStartTime
{
get => (DateTime)GetValue(TouchStartTimeProperty);
set => SetValue(TouchStartTimeProperty, value);
}
public static readonly BindableProperty TouchEndTimeProperty = BindableProperty.Create(
nameof(TouchEndTime),
typeof(DateTime),
typeof(TouchView),
new DateTime());
public DateTime TouchEndTime
{
get => (DateTime)GetValue(TouchEndTimeProperty);
set => SetValue(TouchEndTimeProperty, value);
}
public void TouchStarted()
{
StartTouchTimer();
TouchStart(this, default);
IsTouching = true;
}
public void TouchEnded()
{
EndTouchTimer();
IsTouching = false;
}
private bool isStopRequested;
private void StartTouchTimer()
{
isStopRequested = false;
TouchStartTime = DateTime.Now;
Device.StartTimer(TimeSpan.FromSeconds(1/60f), ()=>
{
if (isStopRequested)
return false;
TouchDuration = DateTime.Now - TouchStartTime;
if (TouchDuration >= TimeSpan.FromSeconds(MaxTouchDuration))
EndTouchTimer();
return true;
});
}
private void EndTouchTimer()
{
TouchEndTime = DateTime.Now;
TouchDuration = TouchEndTime - TouchStartTime;
isStopRequested = true;
TouchEnd(this, default);
}
}
}
答案 0 :(得分:0)
找到答案:
在OnTouchEvent
方法中,代替return base.OnTouchEvent(e);
强制该方法返回true
。