Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,28 @@ void ClearLayoutListener()
_carouselViewLayoutListener = null;
}

// https://github.com/dotnet/maui/issues/13323
// CarouselView is a full-page pager; child-initiated rectangle scroll requests
// (e.g. EditText cursor positioning) must not scroll the carousel.
public override bool RequestChildRectangleOnScreen(
global::Android.Views.View child,
global::Android.Graphics.Rect rect,
bool immediate)
{
return false;
}

// https://github.com/dotnet/maui/issues/13323
// base.RequestChildFocus starts a focus-driven scroll; cancel it after
// calling base so that focus itself still works normally.
public override void RequestChildFocus(
global::Android.Views.View child,
global::Android.Views.View focused)
{
base.RequestChildFocus(child, focused);
StopScroll();
}

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// If the height or width are unbounded and the user is set to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#nullable enable
#nullable enable
Comment thread
praveenkumarkarunanithi marked this conversation as resolved.
override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void
~override Microsoft.Maui.Controls.Handlers.Items.MauiCarouselRecyclerView.RequestChildFocus(Android.Views.View! child, Android.Views.View! focused) -> void
~override Microsoft.Maui.Controls.Handlers.Items.MauiCarouselRecyclerView.RequestChildRectangleOnScreen(Android.Views.View! child, Android.Graphics.Rect! rect, bool immediate) -> bool
~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView<TItemsView, TAdapter, TItemsViewSource>.OnInterceptTouchEvent(Android.Views.MotionEvent e) -> bool
~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView<TItemsView, TAdapter, TItemsViewSource>.OnTouchEvent(Android.Views.MotionEvent e) -> bool
100 changes: 100 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue13323.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 13323,
"CarouselView on Android does not work if HorizontalTextAlignment in Entry is not Start",
PlatformAffected.Android)]
public class Issue13323 : ContentPage
{
public Issue13323()
{
var items = new[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };

var positionLabel = new Label
{
AutomationId = "PositionLabel",
Text = "Position:0",
HorizontalOptions = LayoutOptions.Center,
};

var carousel = new CarouselView
{
AutomationId = "CarouselView13323",
ItemsSource = items,
Loop = false,
HeightRequest = 250,
ItemTemplate = new DataTemplate(() =>
{
var entry = new Entry
{
AutomationId = "CenterEntry",
Placeholder = "Tap me",
HorizontalTextAlignment = TextAlignment.Center,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
Comment thread
praveenkumarkarunanithi marked this conversation as resolved.

return new Border
{
HeightRequest = 200,
Content = new VerticalStackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = { entry }
}
};
})
};

carousel.PositionChanged += (s, e) =>
{
positionLabel.Text = $"Position:{carousel.Position}";
};

var loopPositionLabel = new Label
{
AutomationId = "LoopPositionLabel",
Text = "LoopPosition:0",
HorizontalOptions = LayoutOptions.Center,
};

var loopCarousel = new CarouselView
{
AutomationId = "LoopCarouselView13323",
ItemsSource = items,
Loop = true,
HeightRequest = 250,
ItemTemplate = new DataTemplate(() =>
{
var entry = new Entry
{
AutomationId = "LoopCenterEntry",
Placeholder = "Tap me",
HorizontalTextAlignment = TextAlignment.Center,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
Comment thread
praveenkumarkarunanithi marked this conversation as resolved.

return new Border
{
HeightRequest = 200,
Content = new VerticalStackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = { entry }
}
};
})
};

loopCarousel.PositionChanged += (s, e) =>
{
loopPositionLabel.Text = $"LoopPosition:{loopCarousel.Position}";
};

Content = new ScrollView
{
Content = new VerticalStackLayout
{
Children = { positionLabel, carousel, loopPositionLabel, loopCarousel }
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Microsoft.Maui.TestCases.Tests;
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.AppUITests.Issues;

public class Issue13323 : _IssuesUITest
Comment thread
praveenkumarkarunanithi marked this conversation as resolved.
{
public Issue13323(TestDevice device) : base(device) { }

public override string Issue => "CarouselView on Android does not work if HorizontalTextAlignment in Entry is not Start";

[Test]
[Category(UITestCategories.CarouselView)]
public void CarouselView_EntryTap_DoesNotChangePosition()
{
App.WaitForElement("CarouselView13323");

App.SwipeRightToLeft("CarouselView13323");
App.SwipeRightToLeft("CarouselView13323");

App.WaitForElement("Position:2");

App.Tap("CenterEntry");

// Position must remain at 2 after tapping Center-aligned Entry
App.WaitForElement("Position:2");

var positionAfter = App.FindElement("PositionLabel").GetText();
Comment thread
praveenkumarkarunanithi marked this conversation as resolved.
Comment thread
praveenkumarkarunanithi marked this conversation as resolved.
Assert.That(positionAfter, Is.EqualTo("Position:2"), $"CarouselView jumped after tapping Center-aligned Entry: {positionAfter}");

App.DismissKeyboard();
App.WaitForKeyboardToHide();
}

[Test]
[Category(UITestCategories.CarouselView)]
public void CarouselView_Loop_EntryTap_DoesNotChangePosition()
{
App.WaitForElement("LoopCarouselView13323");

App.SwipeRightToLeft("LoopCarouselView13323");
App.SwipeRightToLeft("LoopCarouselView13323");

App.WaitForElement("LoopPosition:2");

App.Tap("LoopCenterEntry");

// Position must remain at 2 after tapping Center-aligned Entry with Loop=true
App.WaitForElement("LoopPosition:2");

var positionAfter = App.FindElement("LoopPositionLabel").GetText();
Assert.That(positionAfter, Is.EqualTo("LoopPosition:2"), $"CarouselView (Loop=true) jumped after tapping Center-aligned Entry: {positionAfter}");
Comment thread
praveenkumarkarunanithi marked this conversation as resolved.
Outdated
}
}
Loading