Skip to content

Conversation

@Dhivya-SF4094
Copy link
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Issue Details:

When a CarouselView is used with nested scrollable content (e.g., CollectionView), swipe gestures are not handled correctly. By default, the CarouselView intercepts all touch events, including vertical swipes, even when the intent is to scroll the child view.

Root Cause

By default, MauiCarouselRecyclerView overrides OnInterceptTouchEvent and returns true, meaning it intercepts touch gestures before child views (like CollectionView) can process them.
As a result, Vertical swipes however, are also partially intercepted by the Carousel, even when the intent is to scroll inside the nested CollectionView.
This causes a conflict: vertical gestures intended for the inner CollectionView sometimes trigger an unwanted item transition in the CarouselView.

Description of Change

The touch interception logic was updated to properly distinguish swipe directions. Instead of intercepting all gestures, the implementation now compares horizontal and vertical movement to decide whether the event should be handled by the parent control or delegated to the child.

Validated the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Issues Fixed:

Fixes #22507

Screenshots

Before  After 
 
22507_Android_BeforeFix.mov
  
22507_Android_AfterFix.mov

@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Sep 26, 2025
@dotnet-policy-service
Copy link
Contributor

Hey there @@Dhivya-SF4094! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service dotnet-policy-service bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Sep 26, 2025
@jsuarezruiz
Copy link
Contributor

/azp run MAUI-UITests-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jsuarezruiz jsuarezruiz added platform/android area-controls-collectionview CollectionView, CarouselView, IndicatorView labels Sep 29, 2025
@jsuarezruiz
Copy link
Contributor

/rebase

@Dhivya-SF4094 Dhivya-SF4094 marked this pull request as ready for review October 1, 2025 03:54
Copilot AI review requested due to automatic review settings October 1, 2025 03:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an issue where CarouselView incorrectly intercepts vertical swipe gestures on Android, preventing proper scrolling of nested scrollable content like CollectionView. The fix improves touch event handling by comparing horizontal and vertical movement to determine whether gestures should be handled by the CarouselView or delegated to child views.

Key changes:

  • Modified touch interception logic in MauiCarouselRecyclerView to distinguish between horizontal and vertical swipes
  • Added comprehensive UI tests to validate the fix across platforms
  • Ensured nested scrollable content can scroll vertically without unwanted CarouselView item transitions

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
MauiCarouselRecyclerView.cs Enhanced OnInterceptTouchEvent method with directional swipe detection logic
Issue22507.cs (HostApp) Created test page with CarouselView containing nested CollectionView for reproducing the issue
Issue22507.cs (Tests) Added automated UI test to verify vertical scrolling works correctly within CarouselView

Comment on lines +72 to +78
bool ShouldDelegateToChild(float deltaX, float deltaY)
{
float absDeltaX = Math.Abs(deltaX);
float absDeltaY = Math.Abs(deltaY);

return IsHorizontal ? absDeltaY > absDeltaX : absDeltaX > absDeltaY;
}
Copy link

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ShouldDelegateToChild method lacks documentation explaining its logic for determining when to delegate touch events to child views. Consider adding a summary comment explaining that it compares horizontal vs vertical movement magnitudes to determine gesture direction.

Copilot uses AI. Check for mistakes.
@jsuarezruiz
Copy link
Contributor

/azp run MAUI-UITests-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

float absDeltaX = Math.Abs(deltaX);
float absDeltaY = Math.Abs(deltaY);

return IsHorizontal ? absDeltaY > absDeltaX : absDeltaX > absDeltaY;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should only evaluate direction after a minimum movement threshold?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsuarezruiz, I have updated the logic to ensure the scroll direction is only evaluated after the user’s touch movement exceeds a minimum threshold. To achieve this, used ViewConfiguration.Get(context).ScaledTouchSlop, which provides the platform-defined distance in pixels that indicates a meaningful gesture.

// Wait for the test page to load
App.WaitForElement("Issue22507Label");

App.ScrollDown("Issue22507CollectionView");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can include another test that start scrolling vertical and then horizontally?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsuarezruiz, Added an additional test that starts with a vertical scroll followed by a horizontal swipe to validate gesture handling


List<View> _oldViews;
CarouselViewOnGlobalLayoutListener _carouselViewLayoutListener;
float _touchSlop;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While Android touch events typically fire on UI thread, could be accessed from different threads?

Can use local variables to avoid holding state across events or use volatile.

_touchSlop = ViewConfiguration.Get(context).ScaledTouchSlop;
}

public bool IsSwipeEnabled { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsSwipeEnabled property gates the entire gesture logic but isn't documented. Can include a comment?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-collectionview CollectionView, CarouselView, IndicatorView community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] CarouselView behaves strangely when swiping vertically in view

2 participants