[A] PanGestureRecognizer will consistently send Completed event (#313)
* Adjust gallery page for reproduction * [A] Forward OnTouchEvent to Listener... ...and end scrolling on Up.
This commit is contained in:
Родитель
1b7250167f
Коммит
ab0daa1947
|
@ -8,33 +8,54 @@ namespace Xamarin.Forms.Controls
|
|||
{
|
||||
public class PanGestureGalleryPage : ContentPage
|
||||
{
|
||||
public class PanCompleteArgs : EventArgs
|
||||
{
|
||||
public PanCompleteArgs(string message) { Message = message; }
|
||||
public string Message
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
}
|
||||
|
||||
public class PanContainer : ContentView
|
||||
{
|
||||
public PanContainer ()
|
||||
double _x, _y;
|
||||
double _currentScale = 1;
|
||||
|
||||
public EventHandler<PanCompleteArgs> PanCompleted;
|
||||
|
||||
public PanContainer()
|
||||
{
|
||||
var pan = new PanGestureRecognizer
|
||||
GestureRecognizers.Add(GetPinch());
|
||||
GestureRecognizers.Add(GetPan());
|
||||
}
|
||||
|
||||
PanGestureRecognizer GetPan()
|
||||
{
|
||||
var pan = new PanGestureRecognizer();
|
||||
pan.PanUpdated += (s, e) =>
|
||||
{
|
||||
TouchPoints = 1
|
||||
};
|
||||
|
||||
pan.PanUpdated += (object s, PanUpdatedEventArgs e) =>
|
||||
{
|
||||
switch (e.StatusType) {
|
||||
|
||||
case GestureStatus.Started: break;
|
||||
|
||||
switch (e.StatusType)
|
||||
{
|
||||
case GestureStatus.Running:
|
||||
Content.TranslationX = e.TotalX;
|
||||
Content.TranslationY = e.TotalY;
|
||||
break;
|
||||
|
||||
default:
|
||||
Content.TranslationX = Content.TranslationY = 0;
|
||||
case GestureStatus.Completed:
|
||||
_x = Content.TranslationX;
|
||||
_y = Content.TranslationY;
|
||||
|
||||
PanCompleted?.Invoke(s, new PanCompleteArgs($"x: {_x}, y: {_y}"));
|
||||
break;
|
||||
}
|
||||
};
|
||||
return pan;
|
||||
}
|
||||
|
||||
var pinch = new PinchGestureRecognizer ();
|
||||
PinchGestureRecognizer GetPinch()
|
||||
{
|
||||
var pinch = new PinchGestureRecognizer();
|
||||
|
||||
double xOffset = 0;
|
||||
double yOffset = 0;
|
||||
|
@ -43,14 +64,16 @@ namespace Xamarin.Forms.Controls
|
|||
pinch.PinchUpdated += (sender, e) =>
|
||||
{
|
||||
|
||||
if (e.Status == GestureStatus.Started) {
|
||||
if (e.Status == GestureStatus.Started)
|
||||
{
|
||||
startScale = Content.Scale;
|
||||
Content.AnchorX = Content.AnchorY = 0;
|
||||
}
|
||||
if (e.Status == GestureStatus.Running) {
|
||||
|
||||
if (e.Status == GestureStatus.Running)
|
||||
{
|
||||
_currentScale += (e.Scale - 1) * startScale;
|
||||
_currentScale = Math.Max (1, _currentScale);
|
||||
_currentScale = Math.Max(1, _currentScale);
|
||||
|
||||
var renderedX = Content.X + xOffset;
|
||||
var deltaX = renderedX / Width;
|
||||
|
@ -65,32 +88,42 @@ namespace Xamarin.Forms.Controls
|
|||
double targetX = xOffset - (originX * Content.Width) * (_currentScale - startScale);
|
||||
double targetY = yOffset - (originY * Content.Height) * (_currentScale - startScale);
|
||||
|
||||
Content.TranslationX = targetX.Clamp (-Content.Width * (_currentScale - 1), 0);
|
||||
Content.TranslationY = targetY.Clamp (-Content.Height * (_currentScale - 1), 0);
|
||||
Content.TranslationX = targetX.Clamp(-Content.Width * (_currentScale - 1), 0);
|
||||
Content.TranslationY = targetY.Clamp(-Content.Height * (_currentScale - 1), 0);
|
||||
|
||||
Content.Scale = _currentScale;
|
||||
}
|
||||
if (e.Status == GestureStatus.Completed) {
|
||||
|
||||
if (e.Status == GestureStatus.Completed)
|
||||
{
|
||||
xOffset = Content.TranslationX;
|
||||
yOffset = Content.TranslationY;
|
||||
}
|
||||
};
|
||||
|
||||
GestureRecognizers.Add (pinch);
|
||||
|
||||
GestureRecognizers.Add (pan);
|
||||
return pinch;
|
||||
}
|
||||
|
||||
double _currentScale = 1;
|
||||
}
|
||||
|
||||
public PanGestureGalleryPage ()
|
||||
public PanGestureGalleryPage()
|
||||
{
|
||||
var image = new Image { Source = "http://placehold.it/2000x2000", BackgroundColor = Color.Gray, WidthRequest = 2000, HeightRequest = 2000, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
|
||||
var box = new Image
|
||||
{
|
||||
BackgroundColor = Color.Gray,
|
||||
WidthRequest = 2000,
|
||||
HeightRequest = 2000,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
HorizontalOptions = LayoutOptions.Center
|
||||
};
|
||||
|
||||
var panme = new PanContainer { Content = image };
|
||||
var label = new Label { Text = "Use two fingers to pinch. Use one finger to pan." };
|
||||
|
||||
Content = new StackLayout { Children = { new Label { Text = "Use two fingers to pinch. Use one finger to pan." }, panme }, Padding = new Thickness (20) };
|
||||
var panme = new PanContainer { Content = box };
|
||||
panme.PanCompleted += (s, e) =>
|
||||
{
|
||||
label.Text = e.Message;
|
||||
};
|
||||
|
||||
Content = new StackLayout { Children = { label, panme }, Padding = new Thickness(20) };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,12 +38,18 @@ namespace Xamarin.Forms.Platform.Android
|
|||
}
|
||||
|
||||
// This is needed because GestureRecognizer callbacks can be delayed several hundred milliseconds
|
||||
// which can result in the need to resurect this object if it has already been disposed. We dispose
|
||||
// which can result in the need to resurrect this object if it has already been disposed. We dispose
|
||||
// eagerly to allow easier garbage collection of the renderer
|
||||
internal InnerGestureListener(IntPtr handle, JniHandleOwnership ownership) : base(handle, ownership)
|
||||
{
|
||||
}
|
||||
|
||||
internal void OnTouchEvent(MotionEvent e)
|
||||
{
|
||||
if (e.Action == MotionEventActions.Up)
|
||||
EndScrolling();
|
||||
}
|
||||
|
||||
bool GestureDetector.IOnDoubleTapListener.OnDoubleTap(MotionEvent e)
|
||||
{
|
||||
if (_tapDelegate == null || _tapGestureRecognizers == null)
|
||||
|
|
|
@ -98,6 +98,9 @@ namespace Xamarin.Forms.Platform.Android
|
|||
ScaleGestureDetectorCompat.SetQuickScaleEnabled(_scaleDetector.Value, true);
|
||||
handled = _scaleDetector.Value.OnTouchEvent(e);
|
||||
}
|
||||
|
||||
_gestureListener?.OnTouchEvent(e);
|
||||
|
||||
return _gestureDetector.Value.OnTouchEvent(e) || handled;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче