Xamarin.forms: [Bug][Android] Vertical ScrollView can't scroll after scrolling a nested horizontal ScrollView

Created on 13 Dec 2019  路  8Comments  路  Source: xamarin/Xamarin.Forms

Description

On Android devices only, you can't scroll a vertical ScrollView anymore after scrolling a nested horizontal ScrollView, when panning on entries.
If you don't scroll the nested horizontal scrollview, you can scroll vertically, even if you put your finger on entries.
After scrolling vertically, starting from the horizontal scrollview (if you put your finger on the nested horizontal scrollview), the issue disappears : you can scroll back vertically if you put your finger on entries.
If my explanaitions aren't clear enough, please check the GIF below to see how it behaves.

Steps to Reproduce

  1. Clone https://github.com/EmmanuelJego/XFormsNestedScrollBug.git and launch the app, or create your own ContentPage with a vertical scrollview with a nested horizontal scrollview, and add entriy(ies) to the vertical one.
  2. First, scroll the vertical scrollview (up or down) (you can start scrolling from a light gray box or an entry, both work as expected).
  3. Then, scroll the horizontal scrollview (left or right) (the one with small darker gray boxes in my sample). No problem so far.
  4. Now, try to scroll the vertical scrollview again (up or down) (without starting scrolling from the dark gray boxes, otherwise the bug wouldn't show up, as explained in 5th step) : if you start scrolling from a light gray box, it works as expected, just as before. But then if you try to scroll starting from an entry, it doesn't scroll down nor up. It looks like the scrollview looses the focus.
  5. If you want the vertical scrollview to work back again, start scrolling vertically starting from the horizontal scrollview (put your finger on a dark gray box, and scroll up or down) : then, the bug disappears.

Expected Behavior

The parent vertical scrollview scrolls normally, even after scroll the nested horizontal scrollview.

Actual Behavior

The parent vertical scrollview doesn't scroll after scrolling the nested horizontal scrollview, only if you start the vertical scrolling from an entry.

Basic Information

  • Version with issue: Xamarinf.Forms 4.4.0.991265
  • Tested Android devices/versions:

    • Moto G5 / Android 7.0

    • Samsung Galaxy S10e / Android 9.0

    • Xiaomi Mi 9t / Android 9.0

    • Samsung Galaxy Tab A (tablet) / Android 7.1

    • Android emulator 9.0

    • Android emulator 6.0

Screenshots


20191213_103353

Reproduction Link


https://github.com/EmmanuelJego/XFormsNestedScrollBug.git

5 help wanted Android bug up-for-grabs

Most helpful comment

Hi ppl,
I think I've found a workaround. After creating this custom renderer to my project, the embedded scrollviews with vertical and horizontal ones, work again, as expected.
It might need some additional polish, but it works :)

using Android.Content;
using Android.Support.V4.View;
using Android.Views;
using MyRenderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using static Android.Views.GestureDetector;

[assembly: Xamarin.Forms.ExportRenderer(typeof(ScrollView), typeof(ScrollViewCustomRenderer))]
namespace MyRenderers
{
    public class ScrollViewCustomRenderer : ScrollViewRenderer, IOnGestureListener
    {
        private GestureDetectorCompat gestureDetector;

        public ScrollViewCustomRenderer(Context context) : base(context)
        {
            NestedScrollingEnabled = true;

            gestureDetector = new GestureDetectorCompat(context, this);
        }

        public bool OnDown(MotionEvent e)
        {
            StartNestedScroll(ScrollAxis.None);

            return false;
        }

        public bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
        {
            return false;
        }

        public void OnLongPress(MotionEvent e)
        {
        }

        public bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
        {
            DispatchNestedPreScroll((int)distanceX, (int)distanceY, null, null);
            DispatchNestedScroll(0, 0, 0, 0, null);

            return false;
        }

        public void OnShowPress(MotionEvent e)
        {
        }

        public bool OnSingleTapUp(MotionEvent e)
        {
            return false;
        }

        public override bool OnTouchEvent(MotionEvent ev)
        {
            bool handled = gestureDetector.OnTouchEvent(ev);
            if (!handled && ev.Action == MotionEventActions.Up)
            {
                StopNestedScroll();
            }

            return base.OnTouchEvent(ev);
        }
    }
}

All 8 comments

Get build error

MSB3231: Unable to remove directory "obj\Debug\90\android\binclasses". Could not find a part of the path 'BottomNavigationView_OnNavigationItemReselectedListenerImplementor.class'. 0

Can't reproduce. I can swipe up and down left and right in all orders regardless of starting position... please be extra explicit in reproduction steps and actual/expected behavior...

Get build error

MSB3231: Unable to remove directory "obj\Debug\90\android\binclasses". Could not find a part of the path 'BottomNavigationView_OnNavigationItemReselectedListenerImplementor.class'. 0

If somebody else get this error, please try to clean/rebuild the solution. I also got a "path too long" build error so I updated the sample repo, it should be good now.

Can't reproduce. I can swipe up and down left and right in all orders regardless of starting position... please be extra explicit in reproduction steps and actual/expected behavior...

I thought the GIF would be explicit enough since it shows exactly the steps to reproduce the bug and the bug itself (in the beginning the vertical scrollview can scrolls even starting form an entry, then after scrolling the nested horizotal scrollview, it cant anymore). However I edited the issue in order to try to explain a little more the steps to reproduce.

I also included the list of devices on which I reproduced the bug. @kingces95, what was the device on which you could'nt reproduce the bug? I haven't found any yet. Thanks

Same problem here with the exact same situation !
The gif file is really clear and helps to understand and reproduce the problem.

I have the same problems with ScrollView.
Sample appl https://github.com/Savage1024/XFScrollBug
ScrollBUG gif

Same problem here, any workaround?

Hi ppl,
I think I've found a workaround. After creating this custom renderer to my project, the embedded scrollviews with vertical and horizontal ones, work again, as expected.
It might need some additional polish, but it works :)

using Android.Content;
using Android.Support.V4.View;
using Android.Views;
using MyRenderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using static Android.Views.GestureDetector;

[assembly: Xamarin.Forms.ExportRenderer(typeof(ScrollView), typeof(ScrollViewCustomRenderer))]
namespace MyRenderers
{
    public class ScrollViewCustomRenderer : ScrollViewRenderer, IOnGestureListener
    {
        private GestureDetectorCompat gestureDetector;

        public ScrollViewCustomRenderer(Context context) : base(context)
        {
            NestedScrollingEnabled = true;

            gestureDetector = new GestureDetectorCompat(context, this);
        }

        public bool OnDown(MotionEvent e)
        {
            StartNestedScroll(ScrollAxis.None);

            return false;
        }

        public bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
        {
            return false;
        }

        public void OnLongPress(MotionEvent e)
        {
        }

        public bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
        {
            DispatchNestedPreScroll((int)distanceX, (int)distanceY, null, null);
            DispatchNestedScroll(0, 0, 0, 0, null);

            return false;
        }

        public void OnShowPress(MotionEvent e)
        {
        }

        public bool OnSingleTapUp(MotionEvent e)
        {
            return false;
        }

        public override bool OnTouchEvent(MotionEvent ev)
        {
            bool handled = gestureDetector.OnTouchEvent(ev);
            if (!handled && ev.Action == MotionEventActions.Up)
            {
                StopNestedScroll();
            }

            return base.OnTouchEvent(ev);
        }
    }
}

Hi ppl,
I think I've found a workaround. After creating this custom renderer to my project, the embedded scrollviews with vertical and horizontal ones, work again, as expected.
It might need some additional polish, but it works :)

Thanks a lot!

Was this page helpful?
0 / 5 - 0 ratings