Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScrollX and ScrollY values at the ScrollView.Scrolled event are not consistent in ScrollOrientation.Both mode #26931

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.None, 41415, "ScrollX and ScrollY values are not consistent with iOS", PlatformAffected.Android)]
[Issue(IssueTracker.None, 41415, "ScrollX and ScrollY values at the ScrollView.Scrolled event are not consistent in ScrollOrientation.Both mode", PlatformAffected.Android)]
public class Bugzilla41415 : ContentPage
{
const string ButtonId = "ClickId";
const string ButtonText = "Click Me";

float _x;
bool _didXChange, _didYChange;

public Bugzilla41415()
{
var grid = new Grid
Expand All @@ -32,8 +30,6 @@ public Bugzilla41415()

var labelx = new Label();
var labely = new Label();
var labelz = new Label();
var labela = new Label();

var scrollView = new ScrollView
{
Expand All @@ -47,25 +43,6 @@ public Bugzilla41415()
{
labelx.Text = $"x: {(int)Math.Round(args.ScrollX)}";
labely.Text = $"y: {(int)Math.Round(args.ScrollY)}";

// first and second taps
if (_x == 0)
{
if (Math.Round(args.ScrollX) != 0 && Math.Round(args.ScrollX) != 100)
_didXChange = true;
if (Math.Round(args.ScrollY) != 0 && Math.Round(args.ScrollY) != 100)
_didYChange = true;
}
else if (_x == 100)
{
if (Math.Round(args.ScrollX) != _x && Math.Round(args.ScrollX) != _x + 100)
_didXChange = true;
if (Math.Round(args.ScrollY) != 100)
_didYChange = true;
}

labelz.Text = "z: " + _didXChange.ToString();
labela.Text = "a: " + _didYChange.ToString();
};

var button = new Button { AutomationId = ButtonId, Text = ButtonText };
Expand All @@ -74,10 +51,6 @@ public Bugzilla41415()
// reset
labelx.Text = null;
labely.Text = null;
labelz.Text = null;
labela.Text = null;
_didXChange = false;
_didYChange = false;

await scrollView.ScrollToAsync(_x + 100, 100, true);
_x = 100;
Expand All @@ -86,16 +59,12 @@ public Bugzilla41415()
Grid.SetRow(button, 0);
Grid.SetRow(labelx, 1);
Grid.SetRow(labely, 2);
Grid.SetRow(labelz, 3);
Grid.SetRow(labela, 4);
Grid.SetRow(scrollView, 5);
Grid.SetRow(scrollView, 3);

Content = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
Expand All @@ -106,8 +75,6 @@ public Bugzilla41415()
button,
labelx,
labely,
labelz,
labela,
scrollView,
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
#if TEST_FAILS_ON_ANDROID && TEST_FAILS_ON_WINDOWS
// On Android ScrollY and ScrollX values are resetted, Issue: https://github.com/dotnet/maui/issues/26747
// On Windows tests are failing in CI, but not locally. Need to investigate more.
using NUnit.Framework;
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

Expand All @@ -18,7 +15,7 @@ public Bugzilla41415UITests(TestDevice device)
{
}

public override string Issue => "ScrollX and ScrollY values are not consistent with iOS";
public override string Issue => "ScrollX and ScrollY values at the ScrollView.Scrolled event are not consistent in ScrollOrientation.Both mode";

[Test]
public void Bugzilla41415Test()
Expand All @@ -28,15 +25,10 @@ public void Bugzilla41415Test()
App.WaitForElement(ButtonId);
App.WaitForElementTillPageNavigationSettled("x: 100");
App.WaitForElementTillPageNavigationSettled("y: 100");
App.WaitForElement("z: True");
App.WaitForElement("a: True");
App.Tap(ButtonId);
App.WaitForElement(ButtonId);
App.WaitForElementTillPageNavigationSettled("y: 100");
App.WaitForElement("z: True");
App.WaitForElement("a: False");
App.WaitForElementTillPageNavigationSettled("x: 200");
}
}
}
#endif
27 changes: 23 additions & 4 deletions src/Core/src/Handlers/ScrollView/ScrollViewHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,34 @@ static int AdjustSpecForAlignment(int measureSpec, Primitives.LayoutAlignment al

void ScrollChange(object? sender, AndroidX.Core.Widget.NestedScrollView.ScrollChangeEventArgs e)
{
var context = (sender as View)?.Context;
var platformView = sender as MauiScrollView;

if (context == null)
if (platformView?.Context is null)
{
return;
}

VirtualView.VerticalOffset = Context.FromPixels(e.ScrollY);
VirtualView.HorizontalOffset = Context.FromPixels(e.ScrollX);
int scrollX = e.ScrollX;
int scrollY = e.ScrollY;

if (VirtualView.Orientation == ScrollOrientation.Both)
{
if (scrollX == 0)
{
// Need to pass the native HorizontalScrollView's ScrollX position to the virtual view to resolve
// the zero scroll offset issue since the framework returns an improper ScrollX value.
scrollX = platformView.HorizontalScrollOffset;
}

if (scrollY == 0)
{
// Pass the native ScrollView's ScrollY to the virtual view to maintain the correct vertical offset.
scrollY = platformView.ScrollY;
}
}

VirtualView.HorizontalOffset = platformView.Context.FromPixels(scrollX);
VirtualView.VerticalOffset = platformView.Context.FromPixels(scrollY);
}

public static void MapContent(IScrollViewHandler handler, IScrollView scrollView)
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Platform/Android/MauiScrollView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class MauiScrollView : NestedScrollView, IScrollBarView, NestedScrollView
internal float LastY { get; set; }

internal bool ShouldSkipOnTouch;
internal int HorizontalScrollOffset => _hScrollView?.ScrollX ?? 0;

public MauiScrollView(Context context) : base(context)
{
Expand Down
Loading