从 WebView 中的 onFling 调用时 LoadURL/goBack 不起作用

发布于 2024-10-23 00:46:46 字数 1699 浏览 6 评论 0原文

通过查看这里的其他帖子,我已经能够让我的 WebView 响应滑动 - 但有一些问题。我想要完成的是从右向左滑动,就像我的活动中的后退按钮一样。这意味着有时会调用 webview.goBack 或 LoadURL 来转到上一页,或者如果我位于顶部网页,则会调用 super.onBackPressed 来关闭当前的 webview。

后一种情况工作正常,但浏览器控件仅部分工作。如果我打开网络视图并深入两页,然后向后滑动一次,我看不到任何变化。如果我再次向后滑动,网络视图就会关闭。这意味着上一个网页是在第一次向后滑动时加载的,但由于某种原因没有显示在屏幕上。如果我使用设备的后退按钮(它调用与 onFling 完全相同的函数),显示屏将按预期刷新。有谁知道什么可能导致这种行为?这是否与 webview 运动事件覆盖某个地方的动作有关?

相关代码如下。感谢您的浏览。

公共类 WebBrowser 扩展 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();
    }
}

}

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那片花海 2024-10-30 00:46:46

我也有同样的问题。尝试:

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

所以返回总是 false,尽管检测器返回 true。我知道这不是它应该的样子,但它对我有用。

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.

最舍不得你 2024-10-30 00:46:46

阿尔夫走在正确的道路上。需要将“setOnTouchListener”添加到webview中,但不需要在gestureDector上进行拼凑。这是完整的解决方案...

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

这可以通过其他投掷和其他运动事件进行扩展。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文