Skip to content

Commit 28ea8c6

Browse files
Dhivya-SF4094jsuarezruiz
authored andcommitted
Fixed CarouselView behaves strangely when swiping vertically in view
1 parent a53104a commit 28ea8c6

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public class MauiCarouselRecyclerView : MauiRecyclerView<CarouselView, ItemsView
2222
List<View> _oldViews;
2323
CarouselViewOnGlobalLayoutListener _carouselViewLayoutListener;
2424

25+
float _initialTouchX;
26+
float _initialTouchY;
27+
2528
protected CarouselView Carousel => ItemsView as CarouselView;
2629

2730
public MauiCarouselRecyclerView(Context context, Func<IItemsLayout> getItemsLayout, Func<ItemsViewAdapter<CarouselView, IItemsViewSource>> getAdapter) : base(context, getItemsLayout, getAdapter)
@@ -37,9 +40,43 @@ public override bool OnInterceptTouchEvent(MotionEvent ev)
3740
if (!IsSwipeEnabled)
3841
return false;
3942

43+
switch (ev.Action)
44+
{
45+
case MotionEventActions.Down:
46+
_initialTouchX = ev.GetX();
47+
_initialTouchY = ev.GetY();
48+
break;
49+
50+
case MotionEventActions.Move:
51+
float deltaX = ev.GetX() - _initialTouchX;
52+
float deltaY = ev.GetY() - _initialTouchY;
53+
54+
if (ShouldDelegateToChild(deltaX, deltaY))
55+
{
56+
return false;
57+
}
58+
break;
59+
60+
case MotionEventActions.Cancel:
61+
case MotionEventActions.Up:
62+
// Reset initial touch values at the end of the gesture
63+
// to prevent old values from being used if we don't get a Down event
64+
_initialTouchX = 0;
65+
_initialTouchY = 0;
66+
break;
67+
}
68+
4069
return base.OnInterceptTouchEvent(ev);
4170
}
4271

72+
bool ShouldDelegateToChild(float deltaX, float deltaY)
73+
{
74+
float absDeltaX = Math.Abs(deltaX);
75+
float absDeltaY = Math.Abs(deltaY);
76+
77+
return IsHorizontal ? absDeltaY > absDeltaX : absDeltaX > absDeltaY;
78+
}
79+
4380
protected virtual bool IsHorizontal => (Carousel?.ItemsLayout)?.Orientation == ItemsLayoutOrientation.Horizontal;
4481

4582
protected override int DetermineTargetPosition(ScrollToRequestEventArgs args)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using System.Collections.ObjectModel;
2+
3+
namespace Maui.Controls.Sample.Issues;
4+
5+
[Issue(IssueTracker.Github, 22507, "CarouselView behaves strangely when swiping vertically in view", PlatformAffected.Android)]
6+
public class Issue22507 : ContentPage
7+
{
8+
public ObservableCollection<Issue22507Model> ItemsList { get; set; }
9+
10+
public Issue22507()
11+
{
12+
ItemsList = new ObservableCollection<Issue22507Model>
13+
{
14+
new Issue22507Model(
15+
"Page 1",
16+
Enumerable.Range('A', 20)
17+
.Select(c => $"Item {(char)c}")
18+
.ToArray()),
19+
20+
new Issue22507Model(
21+
"Page 2",
22+
Enumerable.Range(1, 20)
23+
.Select(i => $"Item {i}")
24+
.ToArray())
25+
};
26+
Grid mainGrid = new Grid
27+
{
28+
RowDefinitions =
29+
{
30+
new RowDefinition { Height = GridLength.Auto },
31+
new RowDefinition { Height = GridLength.Star }
32+
}
33+
};
34+
// Create CarouselView
35+
var mainCarousel = new CarouselView
36+
{
37+
BackgroundColor = Colors.Yellow,
38+
Margin = new Thickness(10),
39+
IsBounceEnabled = true,
40+
IsSwipeEnabled = true,
41+
Loop = false,
42+
ItemsSource = ItemsList,
43+
ItemTemplate = new DataTemplate(() =>
44+
{
45+
// Grid for each carousel item
46+
var grid = new Grid
47+
{
48+
BackgroundColor = Colors.White,
49+
Padding = 10,
50+
RowDefinitions =
51+
{
52+
new RowDefinition { Height = GridLength.Auto },
53+
new RowDefinition { Height = GridLength.Star }
54+
}
55+
};
56+
57+
// Label for Title
58+
var titleLabel = new Label
59+
{
60+
FontSize = 18,
61+
TextColor = Colors.Black,
62+
Margin = new Thickness(0, 0, 0, 10)
63+
};
64+
titleLabel.SetBinding(Label.TextProperty, "Title");
65+
66+
// CollectionView for nested items
67+
var collectionView = new CollectionView
68+
{
69+
BackgroundColor = Colors.LightBlue,
70+
AutomationId = "Issue22507CollectionView",
71+
ItemTemplate = new DataTemplate(() =>
72+
{
73+
var itemLabel = new Label
74+
{
75+
FontSize = 16,
76+
Padding = 10
77+
};
78+
itemLabel.SetBinding(Label.TextProperty, ".");
79+
return itemLabel;
80+
})
81+
};
82+
collectionView.SetBinding(CollectionView.ItemsSourceProperty, "Items");
83+
84+
grid.Add(titleLabel);
85+
grid.Add(collectionView, 0, 1);
86+
87+
return grid;
88+
})
89+
};
90+
Label label = new Label
91+
{
92+
Text = "Swipe vertically on the items below. CarouselView should not interfere with vertical scrolling.",
93+
AutomationId = "Issue22507Label"
94+
};
95+
mainGrid.Add(label);
96+
Grid.SetRow(label, 0);
97+
mainGrid.Add(mainCarousel);
98+
Grid.SetRow(mainCarousel, 1);
99+
100+
Content = mainGrid;
101+
}
102+
}
103+
104+
public class Issue22507Model
105+
{
106+
public string Title { get; set; }
107+
public ObservableCollection<string> Items { get; set; }
108+
109+
public Issue22507Model(string title, string[] items)
110+
{
111+
Title = title;
112+
Items = new ObservableCollection<string>(items);
113+
}
114+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#if TEST_FAILS_ON_CATALYST // App.SwipeRightToLeft does not scroll to next item in Mac catalyst.
2+
using NUnit.Framework;
3+
using UITest.Appium;
4+
using UITest.Core;
5+
6+
namespace Microsoft.Maui.TestCases.Tests.Issues;
7+
8+
public class Issue22507 : _IssuesUITest
9+
{
10+
public Issue22507(TestDevice testDevice) : base(testDevice)
11+
{
12+
}
13+
public override string Issue => "CarouselView behaves strangely when swiping vertically in view";
14+
15+
[Test]
16+
[Category(UITestCategories.CarouselView)]
17+
public void HandleCarouselVerticalScroll()
18+
{
19+
// Wait for the test page to load
20+
App.WaitForElement("Issue22507Label");
21+
22+
App.ScrollDown("Issue22507CollectionView");
23+
// Swipe horizontally to navigate to the next CarouselView item (Page 2)
24+
App.SwipeRightToLeft();
25+
// wait for page 2
26+
App.WaitForElement("Item 1");
27+
for (int i = 0; i < 2; i++)
28+
{
29+
App.ScrollDown("Issue22507CollectionView", ScrollStrategy.Gesture, 0.99, swipeSpeed: 900);
30+
}
31+
App.WaitForElement("Item 20");
32+
}
33+
}
34+
#endif

0 commit comments

Comments
 (0)