Fling Gesture and Webview in Android

前端 未结 3 873
面向向阳花
面向向阳花 2020-12-03 08:06

I have a webview control that needs to support the fling gesture in Android in order to bring up a new record (load new data). This is occuring in a class that extends Activ

相关标签:
3条回答
  • 2020-12-03 08:47

    @Han, forgive @techiServices his uncalled-for answer.

    The problem with the code above is that in all cases it returns true for onFling and onDown. What you want instead is to return false for the events that you don't handle, or for conditions in those events that you don't handle. Or indeed, in onTouchEvent you could pass the call to the base class by returning

    super.onTouchEvent(event);
    
    0 讨论(0)
  • 2020-12-03 08:53

    Create a GestureListener and a GestureDetector. Call the GestureDetector.onTouchEvent by overriding the webview's onTouchEvent.

    You can also just override the Activity onTouchEvent btw. I can post some code if you need.

    Edit: Code as requested.

    public class Main extends Activity {
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            MyWebView webview = new MyWebView(this);
            setContentView(webview);
        }
    
        class MyWebView extends WebView {
            Context context;
            GestureDetector gd;
    
            public MyWebView(Context context) {
                super(context);
    
                this.context = context;
                gd = new GestureDetector(context, sogl);
            }
    
            @Override
            public boolean onTouchEvent(MotionEvent event) {
                return gd.onTouchEvent(event);
            }
    
            GestureDetector.SimpleOnGestureListener sogl = new GestureDetector.SimpleOnGestureListener() {
                public boolean onDown(MotionEvent event) {
                    return true;
                }
    
                public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
                    if (event1.getRawX() > event2.getRawX()) {
                        show_toast("swipe left");
                    } else {
                        show_toast("swipe right");
                    }
                    return true;
                }
            };
    
            void show_toast(final String text) {
                Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT);
                t.show();
            }
        }
    }
    

    @littleFluffyKitty. I presume by default WebView touch events you mean when it brings up the zoom controls etc? I didn't test that. I have found that implementing ones own gesture detection works best (not sure if it would work best on a WebView though). You need to look at a touch event as three distinct components. The press down, the movement (if any), and the press release, as the press down, move, release always happen.

    If you do a return false on the onDown the action should get passed down to the WebView touch event handler but iirc it stops the subsequent events being passed to the GestureDetector. Which is half the reason why I implement my own which is based on the Android source. iirc I got the idea from the Sony Ericsson Tutorials which is downloadable off the market. It's the 3D list which shows the code and its pretty easy to adapt.

    0 讨论(0)
  • 2020-12-03 09:06

    I updated the code, this will now allow to call native events handlers if user didn't flinged

    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.webkit.WebView;
    
    public class MyWebView extends WebView {
        private boolean flinged;
    
        private static final int SWIPE_MIN_DISTANCE = 320;
        private static final int SWIPE_MAX_OFF_PATH = 250;
        private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    
        public MyWebView(Context context, AttributeSet attrs) {
            super(context, attrs);
            gd = new GestureDetector(context, sogl);
        }
    
        GestureDetector gd;
    
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
             gd.onTouchEvent(event);
             if (flinged) {
                 flinged = false;
                 return true;
             } else {
                 return super.onTouchEvent(event);
             }
        }
    
        GestureDetector.SimpleOnGestureListener sogl = new GestureDetector.SimpleOnGestureListener() {
        // your fling code here
            public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
                if (event1.getX() < 1200 && event1.getX() > 80) {
                    return false;
                }
                if (Math.abs(event1.getY() - event1.getY()) > SWIPE_MAX_OFF_PATH)
                    return false;
                if(event1.getX() - event2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    loadUrl("javascript:changePage('LEFT')");
                    Log.i("Swiped","swipe left");
                    flinged = true;
                } else if (event2.getX() - event1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    loadUrl("javascript:changePage('RIGHT')");
                    Log.i("Swiped","swipe right");
                    flinged = true;
                }
                return true;
            }
        };
    }
    
    0 讨论(0)
提交回复
热议问题