Xamarin.forms: [Bug Android] Scrolls conflicts with ScrollView(s) (CarouselView, CollectionView, ListView)

Created on 24 Jan 2020  Â·  13Comments  Â·  Source: xamarin/Xamarin.Forms

Description

Got a strange interaction when scroll a CollectionView that is embedded inside a parent scrollView (CollectionView) on Android only.
It's also affect CarouselView even if they are implemented with NestedScrollView and ListView.

Steps to Reproduce

  1. Create an Horizontal CarouselView (3 views) |↔|
  2. Incorpore on each view a Vertical CollectionView. | ↕ |
  3. On the header of those vertical collectionView, add a Header with an Horizontal CollectionView |↔|

Expected Behavior

Like in iOS, the embedded scrollView must have priority, where the deepest childScrollView should intercept the touch event (should scroll first).
Also directions should not be affected. (an Horizontal ScrollView should not affect a vertical embedded ScrollView)

Actual Behavior

On Android it's anarchy of scroll conflicts.
On iOS it's smooth!

Reproduction Link

Here the reproduction project =>ScrollConflicts.zip

Workaround

I did not find an efficient workaround for now.

Basic Information

  • Platform Target Frameworks:

    • iOS: LastOne!

    • Android: Android 9.0 (API Level 28)

  • Nuget Packages: Xamarin.Forms 4.0+
  • Affected Devices: Android
carouselview collectionview listview scrollview high impact Android bug

Most helpful comment

We're facing the same issue. In our case, a WebView inside a CarouselView isn't (vertically) scrollable.

All 13 comments

How touch event work on Android
AndroidTouchEvents

This usual workaround should work (like on MapRenderer), but it doesn't.
public override bool OnInterceptTouchEvent(MotionEvent ev) { Control.RequestDisallowInterceptTouchEvent(true); return base.OnInterceptTouchEvent(ev); }
There is no Control element inside the Renderers and the method RequestDisallowInterceptTouchEvent is not available inside the Renderers (CollectionView, CarouselView)

Any workaround for this ?

I think I have the same issue as described here. I have a CarouselView where each item is another View. On one of my views, a child element is a CollectionView. The CollectionView items are displayed but I cannot scroll them; instead, the CarouselView item is scrolled.

I'm also on Android. Is this the same as what is described in this issue?

These all come from components that implemented NestedScrollView interfaces so there's just something getting in the way with the nested elements orchestrating scroll interactions

We're facing the same issue. In our case, a WebView inside a CarouselView isn't (vertically) scrollable.

Having the same problem, one CarouselView with Horizontal CollectionView inside of it. CollectionView can not scroll but CarouselView, Android

Same issue here with ListView inside CarouselView.

Just one more thing. My structure is as follows

  • CarouselView

    • ScrollView

    • ListView

    • ListView

It does work with the first view, but have a scroll conflict with second and every other view no matter of type.
Carousel is horizontally scrollable, its content is vertically scrollable.
Hope it helps.

Any sight of a fix? I'm asking just because I would need to think that UI out some other way.

Thank you.

I had the same problem and the following code helped me to alleviate the situation. (I have this view group hierarchy):

*CarouselView
*StackLayout
*ListView

You only have to create an Android Custom Render for ListView like this and you will see some difference right away:

I hope that helps.

```C#
/* Code starts here *//

[assembly: ExportRenderer(typeof(Xamarin.Forms.ListView), typeof(OneListViewRenderer))]
namespace Yournamespace
{
public class OneListViewRenderer : ListViewRenderer
{
public OneListViewRenderer(Context context) : base(context)
{
}

public override bool OnInterceptTouchEvent(Android.Views.MotionEvent ev)
{
    if (ev.Action == MotionEventActions.Move)
    {
        // Disallow ScrollView to intercept touch Move events.
        this.Parent.RequestDisallowInterceptTouchEvent(true);

    }
     return base.OnInterceptTouchEvent(ev);


}

}
}

@jivanro

it help a little but they are still some conflicts in which view start and should move at first..

This one works perfectly fine:

```
[assembly: ExportRenderer(typeof(TouchEventListView), typeof(TouchEventListViewRender))]
namespace WinmanWarehouse.Droid.CustomRenderers
{
public class TouchEventListViewRender : ListViewRenderer
{
public TouchEventListViewRender(Context context) : base(context)
{
}

    public override bool OnInterceptTouchEvent(Android.Views.MotionEvent ev)
    {
        switch (ev.Action & MotionEventActions.Mask)
        {
            case MotionEventActions.Down:
                var listView = this.Control as Android.Widget.ListView;
                listView.NestedScrollingEnabled = false;
                break;
            case MotionEventActions.Move:
                var listView1 = this.Control as Android.Widget.ListView;
                listView1.NestedScrollingEnabled = true;
                break;
            default:
                break;
        }
        return base.OnInterceptTouchEvent(ev);
    }
}

}

Taken from this forum https://forums.xamarin.com/discussion/173637/listview-inside-carouselview-scroll-vertical-is-almost-impossible

@AnnaBagriy Thanks for the tips, but it works only for the vertical issue.
All embedded possibility could have different issues related to this android bug.

@samhouts no milestone for this issue?
Anyway, we hope that MAUI Android will get more support on this Gap between iOS/Android.

Was this page helpful?
0 / 5 - 0 ratings