PullToRefresharp ignoring drag with ScrollView

Hi there,

I have a PullToRefresharp component with a ScrollView, which does not display the loading header when I drag, under certain conditions. The ScrollView contains a TableLayout which in turn contains a set of TextViews, one for each row. Each TextView has a Click event handler attached, which displays a Toast.

If the TableLayout height exceeds the ScrollView height, ie. A vertical scrollbar is required, everything works correctly. Also, if I remove the Click handlers from the TextViews, the loading header appears as expected. It seems to be a combination of no vertical scrollbar and the existence of a Click event handler that breaks things, it's almost as if the drag event is not reaching the ScrollView.

I've tried this with the latest PullToRefresharp from the Component Store and have also downloaded the GitHub source and built a .dll from that, both produce the same results.

Any help would be appreciated.

Thanks,
Ronny.

Posts

  • RonnyBattyRonnyBatty GBMember

    Ok, I've setup a test project and stepped through the PullToRefresharp code, the ViewWrapper.OnTouchEvent method is never being called.

    I can also re-create the same behaviour using a normal ScrollView, so the problem doesn't lie with the PullToRefresharp component.

    The touch event on the TextView doesn't seem to pass up to its parent when it has a Click handler attached, but does if the ScrollView contents exceed the view window, very strange.

  • RonnyBattyRonnyBatty GBMember

    I've managed to re-create this behaviour with the Java Android SDK, so the problem is not even at the Xamarin level. I think I have a workaround if anyone is interested, the thread seems a bit quiet though so I might be on my own here :(

    It appears that the existence of a click handler on a child within a ScrollView somehow prevents the correct transfer of touch events, but only when a vertical scrollbar is not required.

    This becomes an issue with PullToRefresharp when the ScrollView contains a small number of rows that each implement click handlers. The components ViewWrapper never receives the touch event, so the refresh header can never be pulled down.

    To fix this, I've created a custom view class which is an exact copy of the existing PullToRefresharp.Android.Widget.ScrollView but with the following override method added:

    public override bool OnInterceptTouchEvent(MotionEvent e) {
        if(e.Action == MotionEventActions.Move) {
            return true;
        }
        return false;
    }
    

    I believe this prevents any MotionEvents with a Move action from being passed onto the children and instead lets the ScrollView itself handle it, which then passes it onto the parent ViewWrapper.

    Seems like a bit of a hack to me so if anyone has any opinions then feel free to discuss. Any PullToRefresharp devs out there?

  • RonnyBattyRonnyBatty GBMember

    Update, the previous code breaks the normal scrolling behaviour:

    public override bool OnInterceptTouchEvent(MotionEvent e) {
        if(e.Action == MotionEventActions.Move) {
            // Check if the ScrollView contents fit without a vertical ScrollBar.
            if(((View)GetChildAt(0)).Height <= this.Height) {
                return true;
            }
        }
        return base.OnInterceptTouchEvent(e);
    }
    
Sign In or Register to comment.