我在CarouselPage项目的ContentPage中有一个ScrollView( HorizontalMoveEnable = true; )。
我创建了自己的ZoomScrollViewRenderer,可以放大。我还致力于改善手势识别,以转到CarouselPage的另一页。
当我在ScrollView的开头(X位置= 0)并且向左滑动时,它应该转到左侧页面。当我在ScrollView的末尾(X位置= ContentSize.Width)并且向右滑动时,它应该转到右侧的页面。
问题在于,只有两次滑动后它才能工作,我不知道如何改善它。
希望我能解释我的问题。
请参阅我的ZoomScrollViewRender并帮助改进方法DispatchTouchEvent
public class ZoomScrollViewRenderer : ScrollViewRenderer
{
private Context _context;
private ScaleGestureDetector _scaleDetector;
private bool _isScaleProcess = false;
private float X1 { get; set; }
private float X2 { get; set; }
public ZoomScrollViewRenderer(Context context) : base(context)
{
this._context = context;
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
_scaleDetector = new ScaleGestureDetector(Context, new ClearScaleListener(
scale =>
{
var scrollView = (ZoomScrollView)Element;
var xRatio = scale.FocusX / Width;
var yRatio = scale.FocusY / Height;
scrollView.AnchorX = xRatio;
scrollView.AnchorY = yRatio;
},
scale =>
{
_isScaleProcess = true;
var scrollView = (ZoomScrollView)Element;
var zoom = new Pinch(scale.ScaleFactor, scale.FocusX, scale.FocusY);
scrollView.OnZoom(zoom);
}));
}
}
public override bool DispatchTouchEvent(MotionEvent e)
{
var scrollView = (ZoomScrollView)Element;
// Scale if 2 fingers on screen
if (e.PointerCount == 2)
return _scaleDetector.OnTouchEvent(e);
// Ignore horizontal move when content stretched to the width of the screen
if (!scrollView.HorizontalMoveEnable)
return base.DispatchTouchEvent(e);
// Detect first X position
if (MotionEventActions.Down == e.Action)
{
X1 = e.RawX;
return base.DispatchTouchEvent(e);
}
if (_isScaleProcess)
{
//HACK:
//Prevent letting any touch events from moving the scroll view until all fingers are up from zooming...This prevents the jumping and skipping around after user zooms.
if (MotionEventActions.Up == e.Action)
_isScaleProcess = false;
return false;
}
// Detect second X position
if (MotionEventActions.Up == e.Action
|| MotionEventActions.Cancel == e.Action)
{
X2 = e.RawX;
}
// Left or right swipe
if (X2 - X1 > 0 && scrollView.IsStartScroll
|| X1 - X2 >= 0 && scrollView.IsEndScroll)
{
return base.OnTouchEvent(e);
}
return base.DispatchTouchEvent(e);
}
}
ZoomScrollView.cs 在可移植项目中:
public class ZoomScrollView : ScrollView
{
public event EventHandler<Pinch> Zoom;
public bool HorizontalMoveEnable { get; set; } = false;
public ScrollOrientation ScrollOrientation
{
get => Orientation;
set
{
if (value.Equals(Orientation))
return;
Orientation = value;
}
}
public bool IsStartScroll => Math.Abs(0 - ScrollX) < 10;
public bool IsEndScroll => Math.Abs(ContentSize.Width - Width - ScrollX) < 10;
public virtual void OnZoom(Pinch pinch)
{
Zoom?.Invoke(this, pinch);
}
}