Android: How to detect when a scroll has ended

android detect tap
android detect drag
android detect swipe
android onscroll
detect touch on screen android
android ontouchevent
simpleongesturelistener
android detect touch anywhere on screen

I am using the onScroll method of GestureDetector.SimpleOnGestureListener to scroll a large bitmap on a canvas. When the scroll has ended I want to redraw the bitmap in case the user wants to scroll further ... off the edge of the bitmap, but I can't see how to detect when the scroll has ended (the user has lifted his finger from the screen).

e2.getAction() always seems to return the value 2 so that is no help. e2.getPressure seems to return fairly constant values (around 0.25) until the final onScroll call when the pressure seems to fall to about 0.13. I suppose I could detect this reduction in pressure, but this will be far from foolproof.

There must be a better way: can anyone help, please?

Here is how I solved the problem. Hope this helps.

// declare class member variables
private GestureDetector mGestureDetector;
private OnTouchListener mGestureListener;
private boolean mIsScrolling = false;


public void initGestureDetection() {
        // Gesture detection
    mGestureDetector = new GestureDetector(new SimpleOnGestureListener() {
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            handleDoubleTap(e);
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            handleSingleTap(e);
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // i'm only scrolling along the X axis
            mIsScrolling = true;                
            handleScroll(Math.round((e2.getX() - e1.getX())));
            return true;
        }

        @Override
        /**
         * Don't know why but we need to intercept this guy and return true so that the other gestures are handled.
         * https://code.google.com/p/android/issues/detail?id=8233
         */
        public boolean onDown(MotionEvent e) {
            Log.d("GestureDetector --> onDown");
            return true;
        }
    });

    mGestureListener = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {

            if (mGestureDetector.onTouchEvent(event)) {
                return true;
            }

            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(mIsScrolling ) {
                    Log.d("OnTouchListener --> onTouch ACTION_UP");
                    mIsScrolling  = false;
                    handleScrollFinished();
                };
            }

            return false;
        }
    };

    // attach the OnTouchListener to the image view
    mImageView.setOnTouchListener(mGestureListener);
}

Android: How to detect when a scroll has ended, I am using the onScroll method of GestureDetector.SimpleOnGestureListener to scroll a large bitmap on a canvas. When the scroll has ended I  This example demonstrates how do I detect end of scrollView in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main.xml.

You should take a look at http://developer.android.com/reference/android/widget/Scroller.html. Especially this could be of help (sorted by relevance):

isFinished();
computeScrollOffset();
getFinalY(); getFinalX(); and getCurrY() getCurrX()
getDuration()

This implies that you have to create a Scroller.

If you want to use touching you could also use GestureDetector and define your own canvas scrolling. The following sample is creating a ScrollableImageView and in order to use it you have to define the measurements of your image. You can define your own scrolling range and after finishing your scrolling the image gets redrawn.

http://www.anddev.org/viewtopic.php?p=31487#31487

Depending on your code you should consider invalidate(int l, int t, int r, int b); for the invalidation.

Android: How to detect when a scroll has ended, I am using the onScroll method of GestureDetector.SimpleOnGestureListener to scroll a large bitmap on a canvas. When the scroll has ended I want to redraw  When the scroll has ended I want to redraw the bitmap in case the user wants to scroll further off the edge of the bitmap, but I can't see how to detect when the scroll has ended (the user has lifted his finger from the screen). e2.getAction() always seems to return the value 2 so that is no help.

SimpleOnGestureListener.onFling() 

It seems to take place when a scroll ends (i.e. the user lets the finger go), that's what I am using and it works great for me.

How to detect end of ScrollView in Android?, Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill al This example demonstrates how do I detect end of scrollView in android. makeText(getBaseContext(),"Scroll View bottom reached",Toast. I assume you have connected your actual Android Mobile device with your  I need to detect the start/end and direction of scroll in a recyclerview. The scroll listener has two methods: onScrolled() and onScrollStateChanged() . The first method is called after the scroll is started (indeed is called onScrolled() and not onScrolling()).

Coming back to this after a few months I've now followed a different tack: using a Handler (as in the Android Snake sample) to send a message to the app every 125 milliseconds which prompts it to check whether a Scroll has been started and whether more than 100 milliseconds has elapsed since the last scroll event.

This seems to work pretty well, but if anyone can see any drawbacks or possible improvements I should be grateful to hear of them.

The relevant the code is in the MyView class:

public class MyView extends android.view.View {

...

private long timeCheckInterval = 125; // milliseconds
private long scrollEndInterval = 100;
public long latestScrollEventTime;
public boolean scrollInProgress = false;

public MyView(Context context) {
    super(context);
}

private timeCheckHandler mTimeCheckHandler = new timeCheckHandler();

class timeCheckHandler extends Handler{

        @Override
        public void handleMessage(Message msg) {
        long now = System.currentTimeMillis();
        if (scrollInProgress && (now>latestScrollEventTime+scrollEndInterval)) {
                    scrollInProgress = false;

// Scroll has ended, so insert code here

// which calls doDrawing() method

// to redraw bitmap re-centred where scroll ended

                    [ layout or view ].invalidate();
        }
        this.sleep(timeCheckInterval);
        }

        public void sleep(long delayMillis) {
            this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), delayMillis);
            }
    }
}

@Override protected void onDraw(Canvas canvas){
        super.onDraw(canvas);

// code to draw large buffer bitmap onto the view's canvas // positioned to take account of any scroll that is in progress

}

public void doDrawing() {

// code to do detailed (and time-consuming) drawing // onto large buffer bitmap

// the following instruction resets the Time Check clock // the clock is first started when // the main activity calls this method when the app starts

        mTimeCheckHandler.sleep(timeCheckInterval);
}

// rest of MyView class

}

and in the MyGestureDetector class

public class MyGestureDetector extends SimpleOnGestureListener {

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
        float distanceY) {

    [MyView].scrollInProgress = true;
        long now = System.currentTimeMillis();  
    [MyView].latestScrollEventTime =now;

    [MyView].scrollX += (int) distanceX;
    [MyView].scrollY += (int) distanceY;

// the next instruction causes the View's onDraw method to be called // which plots the buffer bitmap onto the screen // shifted to take account of the scroll

    [MyView].invalidate();

}

// rest of MyGestureDetector class

}

View.OnScrollChangeListener, Note: Some views handle scrolling independently from View and may have their own separate listeners for scroll-type events. For example  So, I said "ok, let's try to make a custom class extending ScrollView, override the onScrollChanged() method, detect the end of the scroll, and act accordingly". I did, but in this line: scroll = (ScrollViewExt) findViewById(R.id.scrollView1);

I was looking into this same issue. I saw Akos Cz answer to your question. I created something similar, but with my version I noticed that it only worked for a regular scroll - meaning one that doesn't generate a fling. But if a fling did get generated - regardless if I processed a fling or not, then it did NOT detect the "ACTION_UP" in "onTouchEvent". Now maybe this was just something with my implementation, but if it was I couldn't figure out why.

After further investigation, I noticed that during a fling, the "ACTION_UP" was passed into "onFling" in "e2" every time. So I figured that must be why it wasn't being handled in "onTouchEvent" in those instances.

To make it work for me I only had to call a method to handle the "ACTION_UP" in "onFling" and then it worked for both types of scrolling. Below are the exact steps I took to implement in my app:

-initialized a "gestureScrolling" boolean to "false" in a constructor.

-I set it to "true" in "onScroll"

-created a method to handle the "ACTION_UP" event. Inside that event, I reset "gestureSCrolling" to false and then did the rest of the processing I needed to do.

-in "onTouchEvent", if an "ACTION_UP" was detected and "gestureScrolling" = true, then I called my method to handle "ACTION_UP"

-And the part that I did that was different was: I also called my method to handle "ACTION_UP" inside of "onFling".

How to detect when a scroll has ended - android, I am using the onScroll method of GestureDetector.SimpleOnGestureListener to scroll a large bitmap on a canvas. When the scroll has ended I want to redraw  Detect start scroll and end scroll in recyclerview. I need to detect the start/end and direction of scroll in a recyclerview. The scroll listener has two methods: onScrolled() and onScrollStateChanged(). The first method is called after the scroll is started (indeed is called onScrolled() and not onScrolling()).

Document: scroll event, Note: In iOS UIWebViews, scroll events are not fired while scrolling is taking place; they are only fired after the scrolling has completed. So, I said "ok, let's try to make a custom class extending ScrollView, override the onScrollChanged() method, detect the end of the scroll, and act accordingly". I did, but in this line: scroll = (ScrollViewExt) findViewById(R.id.scrollView1); it throws a java.lang.ClassCastException.

Xamarin.Forms CollectionView Scrolling, When a user swipes to initiate a scroll, the end position of the scroll can be controlled so position of the item after the scroll has completed, and whether to animate the scroll. For more information, see Detect scrolling. Screenshot of a CollectionView vertical list without snap points, on iOS and Android  To determine if you are at the end of your custom ScrollView you could also use a member variable and store the last y-position. Then you can compare the last y-position with the current scroll position.

How to detect when user scrolls to the bottom of a div, Example 2: This example alerts End of DIV is reached! when the user scrolls to the bottom of the div element with class = div. filter_none. edit close. play_arrow. Android - How to detect end of scroll inside List View Step 1: Set the scroll listener of the list view like below. list .setOnScrollListener( new OnScrollListener() {});

Comments
  • I've added if (e2.getPressure() < 0.15) to the onScroll() method. As expected this sometimes detects the end of the scroll, but not always. Surely there must be a better way!
  • I've now abandoned the getPressure approach. It's too unreliable. Instead I'm checking the cumulative distance scrolled and redrawing the bitmap when this exceeds a defined limit. This is more predictable, but still far from ideal. If anyone has any suggestions for a better approach I should be very pleased to hear them!
  • Of the many answers to this thread thosed that have proved most useful to me have been those from Akos Cz, Aron Cederholm and Mike.
  • Try this link : stackoverflow.com/questions/8181828/…
  • Thanks for your help. Judging by the thread on Google Code Android, which your link refers to, there seems to be some confusion about the consequences of returning "true" or "false". I'll try "return true" in the onDown method and shall report back.
  • Thank you very much indeed for this code. It seems to be the answer to my problem. I thought at first the crucial line in your code was "return true" in the onDown method, but in fact this seems to make no difference in my code. The key point seems to be that, so far as I can see, the GestureDetector is never notified of an ACTION_UP event, so as (you correctly identified) I have to include code in my onTouchListener.onTouch() method to look out for this event at the end of the scroll. Thanks again!
  • Interesting... and very helpful. But in a quick test I seem to be getting a touch-up event before a fling. I want to do different things if a fling is occurring or scrolling has simply stopped. When I detect a touch-up, how do I know if I'm about to get a fling event so that I won't perform my normal scroll-end functionality?
  • @GarretWilson You can use a VelocityTracker to detect the velocity of your motion event, which then you can use to determine if a fling is about to happen. See developer.android.com/reference/android/view/… and/or the following post stackoverflow.com/questions/10155907/…
  • to capture ACTION_UP in onTouchEvent, make sure onFling() return false.
  • Thanks for your suggestions. The Scroller looks as if it is designed to start a scroll in response to a Fling gesture and to continue scrolling for a distance determined by the programmer (somewhat like the Home screen on HTC phones). However, I want the screen image to move with the user's touch. I have followed ideas in the anddev thread in my app. However, so far as I can see this example only draws the buffer image once. My app has an image of potentially unlimited size which needs to be redrawn when the app is idle (after one scroll has finished and before another starts.)