summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/Renderers/AHorizontalScrollView.cs
blob: 4d192dc70e615fd067c8927a71abeb19be72fccb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using Android.Content;
using Android.Views;
using Android.Widget;

namespace Xamarin.Forms.Platform.Android
{
	public class AHorizontalScrollView : HorizontalScrollView
	{
		readonly ScrollViewRenderer _renderer;

		public AHorizontalScrollView(Context context, ScrollViewRenderer renderer) : base(context)
		{
			_renderer = renderer;
		}

		internal bool IsBidirectional { get; set; }

		public override bool OnInterceptTouchEvent(MotionEvent ev)
		{
			// set the start point for the bidirectional scroll; 
			// Down is swallowed by other controls, so we'll just sneak this in here without actually preventing
			// other controls from getting the event.
			if (IsBidirectional && ev.Action == MotionEventActions.Down)
			{
				_renderer.LastY = ev.RawY;
				_renderer.LastX = ev.RawX;
			}

			return base.OnInterceptTouchEvent(ev);
		}

		public override bool OnTouchEvent(MotionEvent ev)
		{
			// If the touch is caught by the horizontal scrollview, forward it to the parent so custom renderers can be notified of the touch.
			var verticalScrollViewerRenderer = Parent as ScrollViewRenderer;
			if (verticalScrollViewerRenderer != null)
			{
				verticalScrollViewerRenderer.ShouldSkipOnTouch = true;
				verticalScrollViewerRenderer.OnTouchEvent(ev);
			}

			// The nested ScrollViews will allow us to scroll EITHER vertically OR horizontally in a single gesture.
			// This will allow us to also scroll diagonally.
			// We'll fall through to the base event so we still get the fling from the ScrollViews.
			// We have to do this in both ScrollViews, since a single gesture will be owned by one or the other, depending
			// on the initial direction of movement (i.e., horizontal/vertical).
			if (IsBidirectional)
			{
				float dX = _renderer.LastX - ev.RawX;
				float dY = _renderer.LastY - ev.RawY;
				_renderer.LastY = ev.RawY;
				_renderer.LastX = ev.RawX;
				if (ev.Action == MotionEventActions.Move)
				{
					var parent = (global::Android.Widget.ScrollView)Parent;
					parent.ScrollBy(0, (int)dY);
					ScrollBy((int)dX, 0);
				}
			}

			return base.OnTouchEvent(ev);
		}

		protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
		{
			base.OnScrollChanged(l, t, oldl, oldt);

			_renderer.UpdateScrollPosition(Forms.Context.FromPixels(l), Forms.Context.FromPixels(t));
		}
	}
}