diff options
author | adrianknight89 <adrianknight89@outlook.com> | 2016-12-06 06:07:29 -0600 |
---|---|---|
committer | Rui Marinho <me@ruimarinho.net> | 2016-12-06 12:07:29 +0000 |
commit | 9dff4c16508452512c5faa36788f65ba6419170e (patch) | |
tree | c10ba4ce6c728e953bf0d94f063cd280197a9c31 | |
parent | 331a7b76db5bc645852b8d50a443f5a205a860d3 (diff) | |
download | xamarin-forms-9dff4c16508452512c5faa36788f65ba6419170e.tar.gz xamarin-forms-9dff4c16508452512c5faa36788f65ba6419170e.tar.bz2 xamarin-forms-9dff4c16508452512c5faa36788f65ba6419170e.zip |
[Android] ScrollView should send correct ScrollX and ScrollY (#394)
* Android should show correct ScrollX and ScrollY when scrolling in both directions
* Adding sample code to demonstrate scrolling
* Orientation fix
* ScrollTo should work for horizontal + vertical scrolling
* Get correct scroll x and y values for ScrollOrientation.Both
* Convert positions to pixels
* Adding unit test to watch out for incorrect animation positioning
* automated test
* improvements
* fixed texts
4 files changed, 186 insertions, 10 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla41415.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla41415.cs new file mode 100644 index 00000000..c16f3734 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla41415.cs @@ -0,0 +1,115 @@ +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 41415, "ScrollX and ScrollY values are not consistent with iOS", PlatformAffected.Android)] + public class Bugzilla41415 : TestContentPage + { + const string ButtonText = "Click Me"; + float _x, _y; + bool _didXChange, _didYChange; + + protected override void Init() + { + var grid = new Grid + { + BackgroundColor = Color.Yellow, + WidthRequest = 1000, + HeightRequest = 1000, + Children = + { + new BoxView + { + WidthRequest = 200, + HeightRequest = 200, + BackgroundColor = Color.Red, + HorizontalOptions = LayoutOptions.Center, + VerticalOptions = LayoutOptions.Center + } + } + }; + + var labelx = new Label(); + var labely = new Label(); + var labelz = new Label(); + var labela = new Label(); + + var scrollView = new ScrollView + { + Orientation = ScrollOrientation.Both, + HorizontalOptions = LayoutOptions.FillAndExpand, + VerticalOptions = LayoutOptions.FillAndExpand + }; + + scrollView.Content = grid; + scrollView.Scrolled += (sender, args) => + { + labelx.Text = $"x: {args.ScrollX}"; + labely.Text = $"y: {args.ScrollY}"; + + // first and second taps + if (_x == 0) + { + if (args.ScrollX != 0 && args.ScrollX != 100) + _didXChange = true; + if (args.ScrollY != 0 && args.ScrollY != 100) + _didYChange = true; + } + else if (_x == 100) + { + if (args.ScrollX != _x && args.ScrollX != _x + 100) + _didXChange = true; + if (args.ScrollY != 100) + _didYChange = true; + } + + labelz.Text = "z: " + _didXChange.ToString(); + labela.Text = "a: " + _didYChange.ToString(); + }; + + var button = new Button { Text = ButtonText }; + button.Clicked += async (sender, e) => + { + // reset + labelx.Text = null; + labely.Text = null; + labelz.Text = null; + labela.Text = null; + _didXChange = false; + _didYChange = false; + + await scrollView.ScrollToAsync(_x + 100, _y + 100, true); + _x = 100; + }; + + Content = new StackLayout { Children = { button, labelx, labely, labelz, labela, scrollView } }; + } + +#if UITEST + + [Test] + public void Bugzilla41415Test() + { + RunningApp.WaitForElement(q => q.Marked(ButtonText)); + RunningApp.Tap(q => q.Marked(ButtonText)); + RunningApp.WaitForElement(q => q.Marked("x: 100")); + RunningApp.WaitForElement(q => q.Marked("y: 100")); + RunningApp.WaitForElement(q => q.Marked("z: True")); + RunningApp.WaitForElement(q => q.Marked("a: True")); + RunningApp.Tap(q => q.Marked(ButtonText)); + RunningApp.WaitForElement(q => q.Marked("x: 200")); + RunningApp.WaitForElement(q => q.Marked("y: 100")); + RunningApp.WaitForElement(q => q.Marked("z: True")); + RunningApp.WaitForElement(q => q.Marked("a: False")); + } + +#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 0decf54f..4c829b44 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 @@ -115,6 +115,7 @@ <Compile Include="$(MSBuildThisFileDirectory)Bugzilla41078.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla40998.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla41205.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Bugzilla41415.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla41418.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla41424.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42069.cs" /> diff --git a/Xamarin.Forms.Core.UnitTests/ScrollViewUnitTests.cs b/Xamarin.Forms.Core.UnitTests/ScrollViewUnitTests.cs index 0ed525c0..46b0e29f 100644 --- a/Xamarin.Forms.Core.UnitTests/ScrollViewUnitTests.cs +++ b/Xamarin.Forms.Core.UnitTests/ScrollViewUnitTests.cs @@ -453,5 +453,36 @@ namespace Xamarin.Forms.Core.UnitTests Assert.AreEqual(100, scroll.Height); Assert.AreEqual(100, scroll.Width); } + + [Test] + public void TestBackToBackBiDirectionalScroll() + { + var scrollView = new ScrollView + { + Orientation = ScrollOrientation.Both, + Platform = new UnitPlatform(), + Content = new Grid + { + WidthRequest = 1000, + HeightRequest = 1000 + } + }; + + var y100Count = 0; + + ((IScrollViewController)scrollView).ScrollToRequested += (sender, args) => + { + if (args.ScrollY == 100) + { + ++y100Count; + } + }; + + scrollView.ScrollToAsync(100, 100, true); + Assert.AreEqual(y100Count, 1); + + scrollView.ScrollToAsync(0, 100, true); + Assert.AreEqual(y100Count, 2); + } } } diff --git a/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs index 2f66d8e8..6db51c23 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs @@ -202,7 +202,18 @@ namespace Xamarin.Forms.Platform.Android internal void UpdateScrollPosition(double x, double y) { if (_view != null) + { + if (_view.Orientation == ScrollOrientation.Both) + { + if (x == 0) + x = Forms.Context.FromPixels(_hScrollView.ScrollX); + + if (y == 0) + y = Forms.Context.FromPixels(ScrollY); + } + Controller.SetScrolledPosition(x, y); + } } static int GetDistance(double start, double position, double v) @@ -248,8 +259,8 @@ namespace Xamarin.Forms.Platform.Android var x = (int)Forms.Context.ToPixels(e.ScrollX); var y = (int)Forms.Context.ToPixels(e.ScrollY); - int currentX = _view.Orientation == ScrollOrientation.Horizontal ? _hScrollView.ScrollX : ScrollX; - int currentY = _view.Orientation == ScrollOrientation.Horizontal ? _hScrollView.ScrollY : ScrollY; + int currentX = _view.Orientation == ScrollOrientation.Horizontal || _view.Orientation == ScrollOrientation.Both ? _hScrollView.ScrollX : ScrollX; + int currentY = _view.Orientation == ScrollOrientation.Vertical || _view.Orientation == ScrollOrientation.Both ? ScrollY : _hScrollView.ScrollY; if (e.Mode == ScrollToMode.Element) { Point itemPosition = Controller.GetScrollPositionForElement(e.Element as VisualElement, e.Position); @@ -275,10 +286,19 @@ namespace Xamarin.Forms.Platform.Android return; } - if (_view.Orientation == ScrollOrientation.Horizontal) - _hScrollView.ScrollTo(distX, distY); - else - ScrollTo(distX, distY); + switch (_view.Orientation) + { + case ScrollOrientation.Horizontal: + _hScrollView.ScrollTo(distX, distY); + break; + case ScrollOrientation.Vertical: + ScrollTo(distX, distY); + break; + default: + _hScrollView.ScrollTo(distX, distY); + ScrollTo(distX, distY); + break; + } }; animator.AnimationEnd += delegate { @@ -291,10 +311,19 @@ namespace Xamarin.Forms.Platform.Android } else { - if (_view.Orientation == ScrollOrientation.Horizontal) - _hScrollView.ScrollTo(x, y); - else - ScrollTo(x, y); + switch (_view.Orientation) + { + case ScrollOrientation.Horizontal: + _hScrollView.ScrollTo(x, y); + break; + case ScrollOrientation.Vertical: + ScrollTo(x, y); + break; + default: + _hScrollView.ScrollTo(x, y); + ScrollTo(x, y); + break; + } Controller.SendScrollFinished(); } } |