summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla25943.cs103
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39331.cs1
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40173.cs183
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla55912.cs6
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2775.cs6
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/TransparentOverlayTests.cs201
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems2
-rw-r--r--Xamarin.Forms.Platform.Android/FastRenderers/GestureManager.cs2
-rw-r--r--Xamarin.Forms.Platform.Android/Platform.cs20
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/BoxRenderer.cs2
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/ImageRenderer.cs2
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs2
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/MotionEventHelper.cs4
-rw-r--r--Xamarin.Forms.Platform.Android/VisualElementExtensions.cs27
-rw-r--r--Xamarin.Forms.Platform.Android/VisualElementRenderer.cs2
-rw-r--r--Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs2
-rw-r--r--Xamarin.Forms.Platform.WinRT/VisualElementTracker.cs2
-rw-r--r--Xamarin.Forms.Platform.iOS/Platform.cs25
18 files changed, 466 insertions, 126 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla25943.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla25943.cs
new file mode 100644
index 00000000..09c6dfc8
--- /dev/null
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla25943.cs
@@ -0,0 +1,103 @@
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+#if UITEST
+using Xamarin.Forms.Core.UITests;
+using Xamarin.UITest;
+using NUnit.Framework;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+#if UITEST
+ [Category(UITestCategories.InputTransparent)]
+#endif
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.Bugzilla, 25943, "[Android] TapGestureRecognizer does not work with a nested StackLayout", PlatformAffected.Android)]
+ public class Bugzilla25943 : TestContentPage
+ {
+ Label _result;
+ int _taps;
+ const string InnerLayout = "innerlayout";
+ const string OuterLayout = "outerlayout";
+ const string Success = "Success";
+
+ protected override void Init()
+ {
+ StackLayout layout = GetNestedStackLayout();
+
+ var tapGestureRecognizer = new TapGestureRecognizer();
+ tapGestureRecognizer.Tapped += (sender, e) =>
+ {
+ _taps = _taps + 1;
+ if (_taps == 2)
+ {
+ _result.Text = Success;
+ }
+ };
+ layout.GestureRecognizers.Add(tapGestureRecognizer);
+
+ Content = layout;
+ }
+
+ public StackLayout GetNestedStackLayout()
+ {
+ _result = new Label();
+
+ var innerLayout = new StackLayout
+ {
+ AutomationId = InnerLayout,
+ HeightRequest = 100,
+ Orientation = StackOrientation.Horizontal,
+ HorizontalOptions = LayoutOptions.Fill,
+ BackgroundColor = Color.AntiqueWhite,
+ Children =
+ {
+ new Label
+ {
+ Text = "inner label",
+ FontSize = 20,
+ HorizontalOptions = LayoutOptions.Center,
+ VerticalOptions = LayoutOptions.CenterAndExpand
+ }
+ }
+ };
+
+ var outerLayout = new StackLayout
+ {
+ AutomationId = OuterLayout,
+ Orientation = StackOrientation.Vertical,
+ BackgroundColor = Color.Brown,
+ Children =
+ {
+ _result,
+ innerLayout,
+ new Label
+ {
+ Text = "outer label",
+ FontSize = 20,
+ HorizontalOptions = LayoutOptions.Center,
+ }
+ }
+ };
+
+ return outerLayout;
+ }
+
+
+#if UITEST
+ [Test]
+ public void VerifyNestedStacklayoutTapsBubble(TransparentOverlayTests.TestPoint test)
+ {
+ RunningApp.WaitForElement(q => q.Marked(InnerLayout));
+ RunningApp.Tap(InnerLayout);
+
+ RunningApp.WaitForElement(q => q.Marked(OuterLayout));
+ RunningApp.Tap(OuterLayout);
+
+ RunningApp.WaitForElement(Success);
+ }
+#endif
+
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39331.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39331.cs
index 4a51cf5b..8ec4131d 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39331.cs
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39331.cs
@@ -12,6 +12,7 @@ namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.BoxView)]
+ [Category(UITestCategories.InputTransparent)]
#endif
[Preserve (AllMembers = true)]
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40173.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40173.cs
index 61d2b1b6..7a584e1d 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40173.cs
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40173.cs
@@ -10,109 +10,118 @@ namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.BoxView)]
+ [Category(UITestCategories.InputTransparent)]
#endif
- [Preserve(AllMembers = true)]
- [Issue(IssueTracker.Bugzilla, 40173, "Android BoxView/Frame not clickthrough in ListView")]
- public class Bugzilla40173 : TestContentPage // or TestMasterDetailPage, etc ...
- {
- const string CantTouchButtonId = "CantTouchButtonId";
- const string CanTouchButtonId = "CanTouchButtonId";
- const string ListTapTarget = "ListTapTarget";
- const string CantTouchFailText = "Failed";
- const string CanTouchSuccessText = "ButtonTapped";
- const string ListTapSuccessText = "ItemTapped";
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.Bugzilla, 40173, "Android BoxView/Frame not clickthrough in ListView")]
+ public class Bugzilla40173 : TestContentPage
+ {
+ const string CantTouchButtonId = "CantTouchButtonId";
+ const string CanTouchButtonId = "CanTouchButtonId";
+ const string ListTapTarget = "ListTapTarget";
+ const string CantTouchFailText = "Failed";
+ const string CanTouchSuccessText = "ButtonTapped";
+ const string ListTapSuccessText = "ItemTapped";
#if UITEST
- [Test]
- public void ButtonBlocked()
- {
- RunningApp.Tap(q => q.All().Marked(CantTouchButtonId));
- RunningApp.WaitForNoElement(q => q.All().Text(CantTouchFailText));
+ [Test]
+ public void ButtonBlocked()
+ {
+ RunningApp.Tap(q => q.All().Marked(CantTouchButtonId));
+ RunningApp.WaitForNoElement(q => q.All().Text(CantTouchFailText));
- RunningApp.Tap(q => q.All().Marked(CanTouchButtonId));
- RunningApp.WaitForElement(q => q.All().Text(CanTouchSuccessText));
+ RunningApp.Tap(q => q.All().Marked(CanTouchButtonId));
+ RunningApp.WaitForElement(q => q.All().Text(CanTouchSuccessText));
#if !__MACOS__
- RunningApp.Tap(q => q.All().Marked(ListTapTarget));
- RunningApp.WaitForElement(q => q.All().Text(ListTapSuccessText));
+ RunningApp.Tap(q => q.All().Marked(ListTapTarget));
+ RunningApp.WaitForElement(q => q.All().Text(ListTapSuccessText));
#endif
- }
+ }
#endif
- protected override void Init()
- {
- var outputLabel = new Label();
- var testButton = new Button
- {
- Text = "Can't Touch This",
- AutomationId = CantTouchButtonId
- };
+ protected override void Init()
+ {
+ var outputLabel = new Label();
+ var testButton = new Button
+ {
+ Text = "Can't Touch This",
+ AutomationId = CantTouchButtonId
+ };
- testButton.Clicked += (sender, args) => outputLabel.Text = CantTouchFailText;
+ testButton.Clicked += (sender, args) => outputLabel.Text = CantTouchFailText;
- var testGrid = new Grid
- {
- Children =
- {
- testButton,
- new BoxView
- {
- Color = Color.Pink.MultiplyAlpha(0.5)
- }
- }
- };
+ var testGrid = new Grid
+ {
+ AutomationId = "testgrid",
+ Children =
+ {
+ testButton,
+ new BoxView
+ {
+ AutomationId = "nontransparentBoxView",
+ Color = Color.Pink.MultiplyAlpha(0.5)
+ }
+ }
+ };
- // BoxView over Button prevents Button click
- var testButtonOk = new Button
- {
- Text = "Can Touch This",
- AutomationId = CanTouchButtonId
- };
+ // BoxView over Button prevents Button click
+ var testButtonOk = new Button
+ {
+ Text = "Can Touch This",
+ AutomationId = CanTouchButtonId
+ };
- testButtonOk.Clicked += (sender, args) => outputLabel.Text = CanTouchSuccessText;
+ testButtonOk.Clicked += (sender, args) =>
+ {
+ outputLabel.Text = CanTouchSuccessText;
+ };
- var testGridOk = new Grid
- {
- Children =
- {
- testButtonOk,
- new BoxView
- {
- Color = Color.Pink.MultiplyAlpha(0.5),
- InputTransparent = true
- }
- }
- };
+ var testGridOk = new Grid
+ {
+ AutomationId = "testgridOK",
+ Children =
+ {
+ testButtonOk,
+ new BoxView
+ {
+ AutomationId = "transparentBoxView",
+ Color = Color.Pink.MultiplyAlpha(0.5),
+ InputTransparent = true
+ }
+ }
+ };
- var testListView = new ListView();
- var items = new[] { "Foo" };
- testListView.ItemsSource = items;
- testListView.ItemTemplate = new DataTemplate(() =>
- {
- var result = new ViewCell
- {
- View = new Grid
- {
- Children =
- {
- new BoxView
- {
- AutomationId = ListTapTarget,
- Color = Color.Pink.MultiplyAlpha(0.5)
- }
- }
- }
- };
+ var testListView = new ListView();
+ var items = new[] { "Foo" };
+ testListView.ItemsSource = items;
+ testListView.ItemTemplate = new DataTemplate(() =>
+ {
+ var result = new ViewCell
+ {
+ View = new Grid
+ {
+ Children =
+ {
+ new BoxView
+ {
+ AutomationId = ListTapTarget,
+ Color = Color.Pink.MultiplyAlpha(0.5)
+ }
+ }
+ }
+ };
- return result;
- });
+ return result;
+ });
- testListView.ItemSelected += (sender, args) => outputLabel.Text = ListTapSuccessText;
+ testListView.ItemSelected += (sender, args) => outputLabel.Text = ListTapSuccessText;
- Content = new StackLayout
- {
- Children = { outputLabel, testGrid, testGridOk, testListView }
- };
- }
- }
+ Content = new StackLayout
+ {
+ AutomationId = "Container Stack Layout",
+ Children = { outputLabel, testGrid, testGridOk, testListView }
+ };
+ }
+ }
} \ No newline at end of file
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla55912.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla55912.cs
index 834244bb..b5a65d88 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla55912.cs
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla55912.cs
@@ -10,7 +10,7 @@ using NUnit.Framework;
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
- [Issue(IssueTracker.Bugzilla, 955912, "Tap event not always propagated to containing Grid/StackLayout",
+ [Issue(IssueTracker.Bugzilla, 55912, "Tap event not always propagated to containing Grid/StackLayout",
PlatformAffected.Android)]
public class Bugzilla55912 : TestContentPage
{
@@ -26,7 +26,7 @@ namespace Xamarin.Forms.Controls.Issues
layout.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
layout.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
- var testGrid = new Grid { BackgroundColor = Color.Red };
+ var testGrid = new Grid { BackgroundColor = Color.Red, AutomationId = "testgrid"};
var gridLabel = new Label
{
AutomationId = GridLabelId,
@@ -37,7 +37,7 @@ namespace Xamarin.Forms.Controls.Issues
Grid.SetRow(testGrid, 1);
testGrid.Children.Add(gridLabel);
- var testStack = new StackLayout { BackgroundColor = Color.Default };
+ var testStack = new StackLayout { BackgroundColor = Color.Default, AutomationId = "teststack"};
var stackLabel = new Label
{
AutomationId = StackLabelId,
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2775.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2775.cs
index a32417f8..3fd30cbc 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2775.cs
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue2775.cs
@@ -5,15 +5,19 @@ using System.Collections.Generic;
using Xamarin.Forms.Internals;
#if UITEST
+using Xamarin.Forms.Core.UITests;
using Xamarin.UITest;
using NUnit.Framework;
#endif
namespace Xamarin.Forms.Controls.Issues
{
+#if UITEST
+ [Category(UITestCategories.InputTransparent)]
+#endif
[Preserve (AllMembers = true)]
[Issue (IssueTracker.Github, 2775, "ViewCell background conflicts with ListView Semi-Transparent and Transparent backgrounds")]
- public class Issue2775 : TestContentPage // or TestMasterDetailPage, etc ...
+ public class Issue2775 : TestContentPage
{
protected override void Init ()
{
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/TransparentOverlayTests.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/TransparentOverlayTests.cs
new file mode 100644
index 00000000..6fd5772d
--- /dev/null
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/TransparentOverlayTests.cs
@@ -0,0 +1,201 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+using System.Linq;
+
+#if UITEST
+using Xamarin.Forms.Core.UITests;
+using Xamarin.UITest;
+using NUnit.Framework;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+#if UITEST
+ [Category(UITestCategories.InputTransparent)]
+#endif
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.None, 618, "Transparent Overlays", PlatformAffected.All)]
+ public class TransparentOverlayTests : TestNavigationPage
+ {
+ readonly Color _transparentColor = Color.Transparent;
+ readonly Color _nontransparentColor = Color.Blue;
+
+ double _transparentOpacity = 0;
+ double _nonTransparentOpacity = 0.2;
+
+ const string Running = "Running...";
+ const string Success = "Success";
+ const string Failure = "Failure";
+ const string DefaultButtonText = "Button";
+ const string Overlay = "overlay";
+ const string AddOverlay = "Add Overlay";
+
+ protected override void Init()
+ {
+ PushAsync(Menu());
+ }
+
+ ContentPage Menu()
+ {
+ var layout = new StackLayout();
+
+ layout.Children.Add(new Label {Text = "Select a test below"});
+
+ foreach (var test in GenerateTests)
+ {
+ layout.Children.Add(MenuButton(test));
+ }
+
+ return new ContentPage { Content = layout };
+ }
+
+ Button MenuButton(TestPoint test)
+ {
+ var button = new Button { Text = test.ToString(), AutomationId = test.AutomationId };
+
+ button.Clicked += (sender, args) => PushAsync(CreateTestPage(test));
+
+ return button;
+ }
+
+ [Preserve(AllMembers = true)]
+ public struct TestPoint
+ {
+ public TestPoint(int i) : this()
+ {
+ AutomationId = $"transparenttest{i}";
+
+ Opacity = (i & (1 << 0)) == 0;
+ InputTransparent = (i & (1 << 1)) == 0;
+ BackgroundColor = (i & (1 << 2)) == 0;
+
+ // Layouts should be input transparent _only_ if they were explicitly told to be
+ ShouldBeTransparent = InputTransparent;
+ }
+
+ internal string AutomationId { get; set; }
+ internal bool ShouldBeTransparent { get; set; }
+
+ internal bool Opacity { get; set; }
+ internal bool InputTransparent { get; set; }
+ internal bool BackgroundColor { get; set; }
+
+ public override string ToString()
+ {
+ return $"O{(Opacity ? "1" : "0")}, B{(BackgroundColor ? "1" : "0")}, I{(InputTransparent ? "1" : "0")}";
+ }
+ }
+
+ static IEnumerable<TestPoint> GenerateTests
+ {
+ get { return Enumerable.Range(0, 8).Select(i => new TestPoint(i)); }
+ }
+
+ ContentPage CreateTestPage(TestPoint test)
+ {
+ Color backgroundColor = test.BackgroundColor? _transparentColor : _nontransparentColor;
+ double opacity = test.Opacity ? _transparentOpacity : _nonTransparentOpacity;
+ bool inputTransparent = test.InputTransparent;
+
+ var grid = new Grid
+ {
+ AutomationId = "testgrid",
+ HorizontalOptions = LayoutOptions.Fill,
+ VerticalOptions = LayoutOptions.Fill
+ };
+
+ grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
+ grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
+ grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
+ grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
+
+ var instructions = new Label
+ {
+ HorizontalOptions = LayoutOptions.Fill,
+ HorizontalTextAlignment = TextAlignment.Center,
+ Text = $"Tap the 'Add Overlay' button, then tap the button labeled 'Button'."
+ + (test.ShouldBeTransparent
+ ? $" If the label below's text changes to {Success} the test has passed."
+ : " If the label below's text remains unchanged, the test has passed.")
+ };
+
+ grid.Children.Add(instructions);
+
+ var results = new Label
+ {
+ HorizontalOptions = LayoutOptions.Fill,
+ HorizontalTextAlignment = TextAlignment.Center,
+ Text = Running
+ };
+
+ grid.Children.Add(results);
+ Grid.SetRow(results, 1);
+
+ var button = new Button
+ {
+ Text = DefaultButtonText,
+ HorizontalOptions = LayoutOptions.Center,
+ VerticalOptions = LayoutOptions.Center
+ };
+
+ button.Clicked += (sender, args) =>
+ {
+ results.Text = test.ShouldBeTransparent ? Success : Failure;
+ };
+
+ var layout = new StackLayout
+ {
+ AutomationId = Overlay,
+ HorizontalOptions = LayoutOptions.Fill,
+ VerticalOptions = LayoutOptions.Fill,
+ BackgroundColor = backgroundColor,
+ InputTransparent = inputTransparent,
+ Opacity = opacity
+ };
+
+ grid.Children.Add(button);
+ Grid.SetRow(button, 3);
+
+ var addOverlayButton = new Button() { Text = AddOverlay };
+ addOverlayButton.Clicked += (sender, args) =>
+ {
+ grid.Children.Add(layout);
+ Grid.SetRow(layout, 3);
+ };
+
+ grid.Children.Add(addOverlayButton);
+ Grid.SetRow(addOverlayButton, 2);
+
+ return new ContentPage { Content = grid, Title = test.ToString()};
+ }
+
+#if UITEST
+ [Test, TestCaseSource(nameof(GenerateTests))]
+ public void VerifyInputTransparent(TestPoint test)
+ {
+ RunningApp.WaitForElement(q => q.Marked(test.AutomationId));
+ RunningApp.Tap(test.AutomationId);
+
+ // Determine the location of the button; we have to do this before adding the overlay because
+ // otherwise the iOS UI tests won't be able to find it consistently
+ var button = RunningApp.WaitForElement(DefaultButtonText);
+ var coords = new Tuple<float, float>(button[0].Rect.CenterX, button[0].Rect.CenterY);
+
+ // Add the overlay
+ RunningApp.WaitForElement(AddOverlay);
+ RunningApp.Tap(AddOverlay);
+
+ // Now tap the screen at the Button's location
+ // We can't do RunningApp.Tap(DefaultButtonText) because the UI tests on iOS can't see it
+ RunningApp.TapCoordinates(coords.Item1, coords.Item2);
+
+ // Check the results
+ RunningApp.WaitForElement(test.ShouldBeTransparent ? Success : Running);
+ }
+#endif
+
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
index 62b97166..c6f34ade 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
@@ -25,6 +25,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla24769.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla25234.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla25662.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Bugzilla25943.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla26501.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla26868.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla27378.cs" />
@@ -287,6 +288,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla52533.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla53362.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45874.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)TransparentOverlayTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Unreported1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla53909.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ListViewNRE.cs" />
diff --git a/Xamarin.Forms.Platform.Android/FastRenderers/GestureManager.cs b/Xamarin.Forms.Platform.Android/FastRenderers/GestureManager.cs
index 8335b9d7..396b12fb 100644
--- a/Xamarin.Forms.Platform.Android/FastRenderers/GestureManager.cs
+++ b/Xamarin.Forms.Platform.Android/FastRenderers/GestureManager.cs
@@ -70,7 +70,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
if (View.GestureRecognizers.Count == 0)
{
handled = true;
- return _motionEventHelper.HandleMotionEvent(parent);
+ return _motionEventHelper.HandleMotionEvent(parent, e);
}
handled = false;
diff --git a/Xamarin.Forms.Platform.Android/Platform.cs b/Xamarin.Forms.Platform.Android/Platform.cs
index add84eb6..4f6b33e9 100644
--- a/Xamarin.Forms.Platform.Android/Platform.cs
+++ b/Xamarin.Forms.Platform.Android/Platform.cs
@@ -1034,14 +1034,31 @@ namespace Xamarin.Forms.Platform.Android
internal class DefaultRenderer : VisualElementRenderer<View>
{
bool _notReallyHandled;
+ readonly MotionEventHelper _motionEventHelper = new MotionEventHelper();
+
internal void NotifyFakeHandling()
{
_notReallyHandled = true;
}
+ public override bool OnTouchEvent(MotionEvent e)
+ {
+ if (base.OnTouchEvent(e))
+ return true;
+
+ return _motionEventHelper.HandleMotionEvent(Parent, e);
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<View> e)
+ {
+ base.OnElementChanged(e);
+
+ _motionEventHelper.UpdateElement(e.NewElement);
+ }
+
public override bool DispatchTouchEvent(MotionEvent e)
{
- #region
+ #region Excessive explanation
// Normally dispatchTouchEvent feeds the touch events to its children one at a time, top child first,
// (and only to the children in the hit-test area of the event) stopping as soon as one of them has handled
// the event.
@@ -1074,7 +1091,6 @@ namespace Xamarin.Forms.Platform.Android
// don't consider the event truly "handled" yet.
// Since a child control short-circuited the normal dispatchTouchEvent stuff, this layout never got the chance for
// IOnTouchListener.OnTouch and the OnTouchEvent override to try handling the touches; we'll do that now
-
return OnTouchEvent(e);
}
diff --git a/Xamarin.Forms.Platform.Android/Renderers/BoxRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/BoxRenderer.cs
index aa19d81c..0737b26f 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/BoxRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/BoxRenderer.cs
@@ -17,7 +17,7 @@ namespace Xamarin.Forms.Platform.Android
if (base.OnTouchEvent(e))
return true;
- return _motionEventHelper.HandleMotionEvent(Parent);
+ return _motionEventHelper.HandleMotionEvent(Parent, e);
}
protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
diff --git a/Xamarin.Forms.Platform.Android/Renderers/ImageRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/ImageRenderer.cs
index 43dac1fe..077cf159 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/ImageRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/ImageRenderer.cs
@@ -111,7 +111,7 @@ namespace Xamarin.Forms.Platform.Android
if (base.OnTouchEvent(e))
return true;
- return _motionEventHelper.HandleMotionEvent(Parent);
+ return _motionEventHelper.HandleMotionEvent(Parent, e);
}
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs
index 0736d17c..f3de6297 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs
@@ -200,7 +200,7 @@ namespace Xamarin.Forms.Platform.Android
if (base.OnTouchEvent(e))
return true;
- return _motionEventHelper.HandleMotionEvent(Parent);
+ return _motionEventHelper.HandleMotionEvent(Parent, e);
}
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Renderers/MotionEventHelper.cs b/Xamarin.Forms.Platform.Android/Renderers/MotionEventHelper.cs
index 4ed06d26..2653ee6e 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/MotionEventHelper.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/MotionEventHelper.cs
@@ -7,9 +7,9 @@ namespace Xamarin.Forms.Platform.Android
VisualElement _element;
bool _isInViewCell;
- public bool HandleMotionEvent(IViewParent parent)
+ public bool HandleMotionEvent(IViewParent parent, MotionEvent motionEvent)
{
- if (_isInViewCell || _element.InputTransparent)
+ if (_isInViewCell || _element.InputTransparent || motionEvent.Action == MotionEventActions.Cancel)
{
return false;
}
diff --git a/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs b/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs
index 800a967e..268b3af2 100644
--- a/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs
+++ b/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs
@@ -16,39 +16,16 @@ namespace Xamarin.Forms.Platform.Android
public static bool ShouldBeMadeClickable(this View view)
{
- var shouldBeClickable = false;
for (var i = 0; i < view.GestureRecognizers.Count; i++)
{
IGestureRecognizer gesture = view.GestureRecognizers[i];
if (gesture is TapGestureRecognizer || gesture is PinchGestureRecognizer || gesture is PanGestureRecognizer)
{
- shouldBeClickable = true;
- break;
+ return true;
}
}
- // do some evil
- // This is required so that a layout only absorbs click events if it is not fully transparent
- // However this is not desirable behavior in a ViewCell because it prevents the ViewCell from activating
- if (view is Layout && view.BackgroundColor != Color.Transparent && view.BackgroundColor != Color.Default)
- {
- Element parent = view.RealParent;
- var skip = false;
- while (parent != null)
- {
- if (parent is ViewCell)
- {
- skip = true;
- break;
- }
- parent = parent.RealParent;
- }
-
- if (!skip)
- shouldBeClickable = true;
- }
-
- return shouldBeClickable;
+ return false;
}
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs b/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs
index 747956c3..80d70ff7 100644
--- a/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs
@@ -93,7 +93,9 @@ namespace Xamarin.Forms.Platform.Android
public override bool OnInterceptTouchEvent(MotionEvent ev)
{
if (!Element.IsEnabled || (Element.InputTransparent && Element.IsEnabled))
+ {
return true;
+ }
return base.OnInterceptTouchEvent(ev);
}
diff --git a/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs b/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs
index 9b711b81..4843fd74 100644
--- a/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs
@@ -548,7 +548,7 @@ namespace Xamarin.Forms.Platform.WinRT
if (control != null)
control.IsEnabled = Element.IsEnabled;
else
- IsHitTestVisible = Element.IsEnabled;
+ IsHitTestVisible = Element.IsEnabled && !Element.InputTransparent;
}
void UpdateTracker()
diff --git a/Xamarin.Forms.Platform.WinRT/VisualElementTracker.cs b/Xamarin.Forms.Platform.WinRT/VisualElementTracker.cs
index d477028f..7e9572bc 100644
--- a/Xamarin.Forms.Platform.WinRT/VisualElementTracker.cs
+++ b/Xamarin.Forms.Platform.WinRT/VisualElementTracker.cs
@@ -449,7 +449,7 @@ namespace Xamarin.Forms.Platform.WinRT
static void UpdateInputTransparent(VisualElement view, FrameworkElement frameworkElement)
{
- frameworkElement.IsHitTestVisible = !view.InputTransparent;
+ frameworkElement.IsHitTestVisible = view.IsEnabled && !view.InputTransparent;
}
static void UpdateOpacity(VisualElement view, FrameworkElement frameworkElement)
diff --git a/Xamarin.Forms.Platform.iOS/Platform.cs b/Xamarin.Forms.Platform.iOS/Platform.cs
index b3542d69..5a442bab 100644
--- a/Xamarin.Forms.Platform.iOS/Platform.cs
+++ b/Xamarin.Forms.Platform.iOS/Platform.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using CoreGraphics;
using Foundation;
using UIKit;
using RectangleF = CoreGraphics.CGRect;
@@ -478,6 +479,30 @@ namespace Xamarin.Forms.Platform.iOS
internal class DefaultRenderer : VisualElementRenderer<VisualElement>
{
+ public override UIView HitTest(CGPoint point, UIEvent uievent)
+ {
+ // UIview hit testing ignores objects which have an alpha of less than 0.01
+ // (see https://developer.apple.com/reference/uikit/uiview/1622469-hittest)
+ // To prevent layouts with low opacity from being implicitly input transparent,
+ // we need to temporarily bump their alpha value during the actual hit testing,
+ // then restore it. If the opacity is high enough or user interaction is disabled,
+ // we don't have to worry about it.
+
+ nfloat old = Alpha;
+ if (UserInteractionEnabled && old <= 0.01)
+ {
+ Alpha = (nfloat)0.011;
+ }
+
+ var result = base.HitTest(point, uievent);
+
+ if (UserInteractionEnabled && old <= 0.01)
+ {
+ Alpha = old;
+ }
+
+ return result;
+ }
}
}
} \ No newline at end of file