[Android] Remove extra scrolling when ScrollOrientation is Both (#1294)

* Repro of 60774

* Remove extra Y-direction scrolling when bidirectional scrolling is on

* Add tests for horizontal and diagonal scrolling
Fix horizontal scroll speed, restore diagonal scrolling and fix speed

* Add test instructions
This commit is contained in:
E.Z. Hart 2018-01-03 03:52:47 -07:00 коммит произвёл Rui Marinho
Родитель 569585a2d4
Коммит c5326abe12
6 изменённых файлов: 237 добавлений и 4 удалений

Просмотреть файл

@ -0,0 +1,84 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Controls.Issues
{
// Manual test to verify that ScrollOrientation.Both scrolls at the correct speed vertically
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Bugzilla, 60774, "[Android] ScrollOrientation.Both doubles the distance of scrolling",
PlatformAffected.Android)]
public class Bugzilla60774 : TestContentPage
{
ScrollOrientation _currentOrientation;
Grid _host;
Label _labelOrientation;
protected override void Init()
{
Title = "ScrollOrientation Vertical/Both";
var grid = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition()
}
};
var layout = new StackLayout();
var instructions = new Label
{
Text = "Scroll the text vertically. Tap 'Change Orientation' to change the ScrollView orientation "
+ "to 'Both'. Scroll the text vertically again - the text should scroll at the same rate. "
+ "If the text scrolls more quickly in one orientation, the test has failed."
};
var button = new Button { Text = "Change Orientation" };
button.Clicked += (sender, args) => ChangeOrientation();
_labelOrientation = new Label { Text = "" };
layout.Children.Add(instructions);
layout.Children.Add(button);
layout.Children.Add(_labelOrientation);
_host = new Grid();
Grid.SetRow(_host, 1);
grid.Children.Add(layout);
grid.Children.Add(_host);
Content = grid;
_currentOrientation = ScrollOrientation.Both;
ChangeOrientation();
}
void ChangeOrientation()
{
_host.Children.Clear();
_currentOrientation = _currentOrientation == ScrollOrientation.Vertical
? ScrollOrientation.Both
: ScrollOrientation.Vertical;
var al = new AbsoluteLayout();
for (var i = 0; i < 100; i++)
{
var label = new Label { Text = "label " + i };
AbsoluteLayout.SetLayoutBounds(label, new Rectangle(0, i * 50, 100, 30));
al.Children.Add(label);
}
var sv = new ScrollView
{
Orientation = _currentOrientation,
Content = al
};
_host.Children.Add(sv);
_labelOrientation.Text = "Current orientation is: " + _currentOrientation;
}
}
}

Просмотреть файл

@ -0,0 +1,85 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Controls.Issues
{
// Manual test to verify that ScrollOrientation.Both scrolls at the correct speed horizontally
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Bugzilla, 60774, "[Android] ScrollOrientation.Both doubles the distance of scrolling",
PlatformAffected.Android, issueTestNumber: 1)]
public class Bugzilla60774_1 : TestContentPage
{
ScrollOrientation _currentOrientation;
Grid _host;
Label _labelOrientation;
protected override void Init()
{
Title = "ScrollOrientation Horizontal/Both";
var grid = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition()
}
};
var layout = new StackLayout();
var instructions = new Label
{
Text = "Scroll the text horizontally. Tap 'Change Orientation' to change the ScrollView orientation "
+ "to 'Both'. Scroll the text horizontally again - the text should scroll at the same rate. "
+ "If the text scrolls more quickly in one orientation, the test has failed."
};
var button = new Button { Text = "Change Orientation" };
button.Clicked += (sender, args) => ChangeOrientation();
_labelOrientation = new Label { Text = "" };
layout.Children.Add(instructions);
layout.Children.Add(button);
layout.Children.Add(_labelOrientation);
_host = new Grid();
Grid.SetRow(_host, 1);
grid.Children.Add(layout);
grid.Children.Add(_host);
Content = grid;
_currentOrientation = ScrollOrientation.Both;
ChangeOrientation();
}
void ChangeOrientation()
{
_host.Children.Clear();
_currentOrientation = _currentOrientation == ScrollOrientation.Horizontal
? ScrollOrientation.Both
: ScrollOrientation.Horizontal;
var al = new AbsoluteLayout();
for (var i = 0; i < 100; i++)
{
var label = new Label { Text = $"{i} label", Margin = 10 };
AbsoluteLayout.SetLayoutBounds(label, new Rectangle(i * 50, 50, 30, 200));
al.Children.Add(label);
}
var sv = new ScrollView
{
Orientation = _currentOrientation,
Content = al
};
_host.Children.Add(sv);
_labelOrientation.Text = "Current orientation is: " + _currentOrientation;
}
}
}

Просмотреть файл

@ -0,0 +1,60 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Controls.Issues
{
// Manual test to make sure diagonal scrolling works at the correct speed
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Bugzilla, 60774, "[Android] ScrollOrientation.Both doubles the distance of scrolling",
PlatformAffected.Android, issueTestNumber: 2)]
public class Bugzilla60774_2 : TestContentPage
{
protected override void Init()
{
Title = "ScrollOrientation Both";
var grid = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition()
}
};
var layout = new StackLayout();
var instructions = new Label
{
Text = "Move the label around. It should be able to move in any direction, with uniform speed. "
+ "If it moves twice as fast vertically as horizontally or vice versa, the test has failed. "
+ "If the label cannot move diagonally, the test has failed."
};
layout.Children.Add(instructions);
grid.Children.Add(layout);
var host = new Grid();
Grid.SetRow(host, 1);
grid.Children.Add(host);
Content = grid;
var al = new AbsoluteLayout();
var label = new Label { Text = "Move this label around", FontSize = 72, Margin = 300 };
AbsoluteLayout.SetLayoutBounds(label, new Rectangle(0, 0, 2000, 2000));
al.Children.Add(label);
var sv = new ScrollView
{
Orientation = ScrollOrientation.Both,
Content = al
};
host.Children.Add(sv);
}
}
}

Просмотреть файл

@ -238,6 +238,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59863_1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59863_2.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla60563.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla60774.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla60774_1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla60774_2.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ButtonBackgroundColorTest.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CarouselAsync.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla34561.cs" />

Просмотреть файл

@ -46,15 +46,15 @@ namespace Xamarin.Forms.Platform.Android
// 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);
// Fall through to base.OnTouchEvent, it'll take care of the X scrolling
}
}

Просмотреть файл

@ -153,19 +153,20 @@ namespace Xamarin.Forms.Platform.Android
if (_isBidirectional && !Element.InputTransparent)
{
float dX = LastX - ev.RawX;
float dY = LastY - ev.RawY;
LastY = ev.RawY;
LastX = ev.RawX;
if (ev.Action == MotionEventActions.Move)
{
ScrollBy(0, (int)dY);
foreach (AHorizontalScrollView child in this.GetChildrenOfType<AHorizontalScrollView>())
{
child.ScrollBy((int)dX, 0);
break;
}
// Fall through to base.OnTouchEvent, it'll take care of the Y scrolling
}
}
return base.OnTouchEvent(ev);
}