问题
By looking at other posts here I've been able to get my WebView to respond to swipes - but with some problems. What I'm trying to accomplish is make a right-to-left swipe act just like the back button in my activity. This means sometimes calling webview.goBack or LoadURL to go to a previous page, or if I'm at the top webpage calling super.onBackPressed to close the current webview.
The latter case works perfectly, but the browser controls are only partially working. If I open the webview and go two pages deep, then swipe back once, I see no change. If I swipe back again, the webview gets closed. This means the previous webpage was loaded on the first back swipe, but it wasn't displayed on the screen for some reason. If I use the device's back button (which calls exactly the same function as my onFling), the display refreshes as expected. Does anyone know what could be causing this behavior? Does it have something to do with the webview motion events overriding an action somewhere?
The relevant pieces of code are below. Thanks for taking a look.
public class WebBrowser extends Activity ... {
...
GestureDetector gestureDetector;
SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() {
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY && Math.abs(e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE) {
goBack();
return true;
}
return false;
}
};
public void onCreate(Bundle savedInstanceState) {
...
gestureDetector = new GestureDetector(gestureListener);
wv.setOnTouchListener(
new View.OnTouchListener() {
public boolean onTouch(View wv, MotionEvent event) {
if(gestureDetector.onTouchEvent(event)) return true;
return false;
}
}
);
private void goBack() {
if (backURL.equals("close")) {
super.onBackPressed();
} else if (!backURL.equals("")) {
wv.loadUrl(backURL);
} else if (wv.canGoBack()) {
wv.goBack();
} else {
super.onBackPressed();
}
}
}
回答1:
I had the same problem. Try:
public void onCreate(Bundle savedInstanceState) {
...
gestureDetector = new GestureDetector(gestureListener);
wv.setOnTouchListener(
new View.OnTouchListener() {
public boolean onTouch(View wv, MotionEvent event) {
gestureDetector.onTouchEvent(event);
return false;
}
}
);
So return always false, although the detector returned true. I know it's not the way it is supposed to be, but it worked for me.
回答2:
Alf is on the right track. The "setOnTouchListener" needs to be added to the webview, but the kludge on gestureDector is not needed. Here is the complete solution...
// LOAD WEBVIEW WITH HTML
wv.loadDataWithBaseURL(null, htmlSource, "text/html", "utf-8", null);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// GESTURE DETECTOR: FLINGLEFT
gestureDetector = new GestureDetector(this,
new GestureDetector.SimpleOnGestureListener()
{
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
if (e1.getX() - e2.getX() > LARGE_MOVE)
{
setResult(Activity.RESULT_OK, new Intent().putExtra("GESTURE", "FLINGLEFT"));
finish();
}
return false;
}
});
// SET ON TOUCH LISTENER
wv.setOnTouchListener(
new View.OnTouchListener() {
public boolean onTouch(View wv, MotionEvent event) {
gestureDetector.onTouchEvent(event);
return false;
}
}
);
This can be extended with other flings and other motion events.
来源:https://stackoverflow.com/questions/5345645/loadurl-goback-not-working-when-called-from-onfling-in-webview