Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using GestureLibrary with ScrollView

As I mentioned on title, app has a ScrollView and a GestureDetector too. Outside of ScrollView's touch events, GestureDetector handling swipe actions like left to right and right to left. They're all working well.

Now I want to add a GestureLibrary -I mean raw- to Activity. I've looked different sources and somehow added properly. Simply, layout looking like this:

<android.gesture.GestureOverlayView
    android:id="@+id/gOverlay"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ScrollView 
        android:id="@+id/content_scroll"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="none">

            </ScrollView>
            <!-- Other views -->
</android.gesture.GestureOverlayView>   

It's drawing as I wanted (the yellow line) but it's not triggering any methods. Here how I implemented OnGesturePerformedListener:

    /*
     * Gestures
     */
    gLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
    if (!gLibrary.load()) { finish(); }
    GestureOverlayView gestureOverlayView = (GestureOverlayView) findViewById(R.id.gOverlay);
    gestureOverlayView.addOnGesturePerformedListener(gestureListener);  

And here is gestureListener:

private OnGesturePerformedListener gestureListener = new OnGesturePerformedListener() {
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
        ArrayList<Prediction> predictions = gLibrary.recognize(gesture);            
        if (predictions.size() > 1) {
            for(Prediction prediction: predictions){
                Log.d("Test", "Looking for gestures");
            }
        }
    }
};

That's all. By the wall, I tried this source code with in different Activity which has no ScrollView and working fine.

Finally, I'm not sure is it about GestureDetector, so that's how app using detector:

public boolean dispatchTouchEvent(MotionEvent ev) {
    if (detector != null) {
        if (detector.onTouchEvent(ev)) {
            return true;
        }
    }
    return super.dispatchTouchEvent(ev);
}

And my SwipeDetector:

private class SwipeDetector extends SimpleOnGestureListener {
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    public boolean onFling(android.view.MotionEvent e1, android.view.MotionEvent e2, float velocityX, float velocityY) {
        if( Math.abs( e1.getY() - e2.getY() ) > SWIPE_MAX_OFF_PATH ) { return false; }
        if( e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs( velocityX ) > SWIPE_THRESHOLD_VELOCITY ) { return false; }
        if( e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs( velocityX ) > SWIPE_THRESHOLD_VELOCITY ) {  filterButton.performClick();return true; }          
        return false;
    }
}

What's wrong with my approach?

like image 513
Ogulcan Orhan Avatar asked Nov 15 '12 13:11

Ogulcan Orhan


People also ask

What is fillViewport in ScrollView?

fillViewport allows scrollView to extend it's height equals to the full height of device screen's height in the cases when the child of scroll view has less height.

What is nested ScrollView in Android?

NestedScrollView is just like ScrollView , but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. Nested scrolling is enabled by default.

What is the difference between ScrollView and RecyclerView?

In the practical on scrolling views, you use ScrollView to scroll a View or ViewGroup . ScrollView is easy to use, but it's not recommended for long, scrollable lists. RecyclerView is a subclass of ViewGroup and is a more resource-efficient way to display scrollable lists.


1 Answers

All touch events in android goes from children to parents. So, scroll view handle all touch events, and you gesture detector does not receives them. You can set touch listener on ScrollView:

    scrollView.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (detector != null) {
                return detector.onTouchEvent(event);
            return false;
        }
    });

You have to check that scroll works as necessary, and you don't consumed scroll events.

like image 127
Jin35 Avatar answered Oct 24 '22 23:10

Jin35