문제

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 Activity. All the examples I've seen show how to implement gesture support for a textview, but nothing for webview.

I need to execute different actions for both left and right flings. Any code help would be appreciated as this totally has me stumped.

Here's my basic onCreate and my class

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.os.Bundle;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;

import android.webkit.WebView;

public class ArticleActivity extends Activity   {

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);



    Window  w = getWindow();

     w.requestFeature(Window.FEATURE_LEFT_ICON);

     WebView webview = new WebView(this);
     setContentView(webview); 



     w.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
     R.drawable.gq);




    setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
    populateFields();
    webview.loadData(question + answer, "text/html", "utf-8");



  //   
}
private void populateFields() {

....


}

}
도움이 되었습니까?

해결책

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.

다른 팁

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;
        }
    };
}

@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);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top