summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/PlatformRenderer.cs
blob: f31b0702f3e33b0cc5ec7674531f562bcb59d99a (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
72
73
74
75
76
77
78
79
80
81
using System;
using Android.App;
using Android.Content;
using Android.Views;
using Android.Widget;

namespace Xamarin.Forms.Platform.Android
{
	internal class PlatformRenderer : ViewGroup
	{
		readonly IPlatformLayout _canvas;
		Point _downPosition;

		DateTime _downTime;

		public PlatformRenderer(Context context, IPlatformLayout canvas) : base(context)
		{
			_canvas = canvas;
			Focusable = true;
			FocusableInTouchMode = true;
		}

		public override bool DispatchTouchEvent(MotionEvent e)
		{
			if (e.Action == MotionEventActions.Down)
			{
				_downTime = DateTime.UtcNow;
				_downPosition = new Point(e.RawX, e.RawY);
			}

			if (e.Action != MotionEventActions.Up)
				return base.DispatchTouchEvent(e);

			global::Android.Views.View currentView = ((Activity)Context).CurrentFocus;
			bool result = base.DispatchTouchEvent(e);

			do
			{
				if (!(currentView is EditText))
					break;

				global::Android.Views.View newCurrentView = ((Activity)Context).CurrentFocus;

				if (currentView != newCurrentView)
					break;

				double distance = _downPosition.Distance(new Point(e.RawX, e.RawY));

				if (distance > Context.ToPixels(20) || DateTime.UtcNow - _downTime > TimeSpan.FromMilliseconds(200))
					break;

				var location = new int[2];
				currentView.GetLocationOnScreen(location);

				float x = e.RawX + currentView.Left - location[0];
				float y = e.RawY + currentView.Top - location[1];

				var rect = new Rectangle(currentView.Left, currentView.Top, currentView.Width, currentView.Height);

				if (rect.Contains(x, y))
					break;

				Context.HideKeyboard(currentView);
				((Activity)Context).Window.DecorView.ClearFocus();
			} while (false);

			return result;
		}

		protected override void OnLayout(bool changed, int l, int t, int r, int b)
		{
			SetMeasuredDimension(r - l, b - t);
			_canvas?.OnLayout(changed, l, t, r, b);
		}

		protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
		{
			SetMeasuredDimension(MeasureSpec.GetSize(widthMeasureSpec), MeasureSpec.GetSize(heightMeasureSpec));
		}
	}
}