【问题标题】:Disabling the WebView double-tab zoom禁用 WebView 双标签缩放
【发布时间】:2012-05-03 05:43:24
【问题描述】:

我在 Android WebView 中显示网页。页面需要缩放以适应 WebView 的可用宽度。

HTML(宽度 550 只是一个例子,可能会改变):

<html> 
<head> 
<meta name="viewport" content="width=550">
...

Java:

mWebView = (WebView)findViewById(R.id.webView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setHorizontalScrollBarEnabled(false);
mWebView.setVerticalScrollBarEnabled(false);
mWebView.requestFocus(View.FOCUS_DOWN);
mWebView.getSettings().setLoadWithOverviewMode(true); // required for scaling
mWebView.getSettings().setUseWideViewPort(true); // required for scaling
mWebView.loadUrl(someUrl);

这很好用,除了一个问题:双标签会触发概览模式和默认比例之间的切换。
有什么方法可以禁用此功能?

顺便说一句:我无法计算代码中的比例,因为加载的页面可能有不同的大小,我事先不知道。我也已经检查了 WebView 的源代码,但没有看到任何我可以覆盖或更改的内容。

【问题讨论】:

    标签: android html webview


    【解决方案1】:

    您可以编写自己的 WebView 实现来实现 OnGestureListener:

    public class MyWebView extends WebView implements OnGestureListener
    

    里面声明一个GestureDetector:

      private GestureDetector             gestureDetector;
    

    实现一个 initWebView() 方法并在构造函数中调用它,如下所示:

    // Best you do this for every WebViewConstructor:
      public AppWebView(Context context) {
      super(context);
      initWebView(); }
    
    private void initWebView(){
       gestureDetector = new GestureDetector(getContext(), this);
       // Do any other customizations for your webview if you like. 
    }
    

    现在实现 OnGestureListener 中的方法并在双击事件时返回 true:

      public boolean onSingleTapConfirmed(MotionEvent e) {
        return false; //Nothing
      }
    
      public boolean onDoubleTap(MotionEvent e) {
        return true; //Nothing
      }
    
      public boolean onDoubleTapEvent(MotionEvent e) {
        return true; //Nothing
      }
    
      public boolean onDown(MotionEvent e) {
        return false; //Nothing
      }
    
      public void onShowPress(MotionEvent e) {
        //Nothing
      }
    
      public boolean onSingleTapUp(MotionEvent e) {
        return false; //Nothing
      }
    
      public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false; //Nothing
      }
    
      public void onLongPress(MotionEvent e) {
        //Nothing
      }
    
      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return false; //Nothing
      }
    

    最后覆盖你的 webview 的 OnTouchEvent 并让它通过事件传递给手势检测器,如下所示:

      @Override
      public boolean onTouchEvent(MotionEvent event) {
        if (gestureDetector.onTouchEvent(event)) return true;
        return super.onTouchEvent(event);
      }
    

    这通常工作得很好,但是这个解决方案有一个基本缺陷:一些未被识别为 DoubleTap 事件的事件可能会导致您的 web 视图缩放。

    我仍在为此寻找解决方案,并将在此处发布我的进展: WebView getting rid of double tap zoom.

    【讨论】:

    • 谢谢,看起来很有希望。我会接受它作为答案而不进行测试。我做了一个 hack,我完全禁用了缩放,将 WebView 传递给 HTML,并从 javascript 中调整内容。不是很好,但很有效。
    【解决方案2】:

    一般来说,更改已知 API 并不是一个好的做法。你可能应该找到一种不同的方法来做到这一点,也许是longClick

    不管怎样,看看this similar question

    【讨论】:

    • 双标签不是我添加的。它内置在 WebView 中,所以我无法更改。无论如何,我不想添加它,我想禁用它。
    • 正如我所说,在原生 UI 中禁用 nuilt 是不好的做法
    【解决方案3】:

    如果可能,请替换 html 中的静态元标记:

    <script>
     var meta = document.createElement("meta");
     meta.setAttribute('name','viewport');
     meta.setAttribute('content','width=device-width, user-scalable=no');
     document.getElementsByTagName('head')[0].appendChild(meta); 
    </script>
    

    此外,您还可以使用一个不错的脚本:FastClick
    它不会等待点击事件,因此速度更快。

    <script type="application/javascript" src="fastclick.js"></script>
    
        <script language="javascript">
    
            window.addEventListener('load', function() {
                FastClick.attach(document.body);
            }, false);
    
    </script>
    

    然后为您的手势检测器设置一个双击监听器。 (在自定义 WebView 中)

    gestureDetector.setOnDoubleTapListener(new OnDoubleTapListener() {
    
        @Override
        public boolean onSingleTapConfirmed( MotionEvent e ) {
            return false;
        }
    
        @Override
        public boolean onDoubleTapEvent( MotionEvent e ) {
    
            return true;
        }
    
        @Override
        public boolean onDoubleTap( MotionEvent e ) {
    
            return true;
        }
    });
    

    重写 onTouchEvent 方法(在自定义 WebView 中):

    @Override
    public boolean onTouchEvent( MotionEvent event ) {
    
        boolean gestureHandled = gestureDetector.onTouchEvent(event);
        int actionMask = event.getActionMasked() & MotionEvent.ACTION_MASK;
        int index = ( event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        int pointId = event.getPointerId(index);
    
        // ignore move events
        if (actionMask == MotionEvent.ACTION_MOVE) {
    
            return super.onTouchEvent(event);
        }
    
        // cancel detected double taps
        if (gestureDetector.onTouchEvent(event)) {
            event.setAction(MotionEvent.ACTION_CANCEL);
            super.onTouchEvent(event);
            return true;
        }
    
        // if you want to ignore multi touch events/taps
        if (pointId != 0) {
    
            System.out.println("KEY multiple points detected");
            return true;
        }
    
        // use single taps
        if (event.getAction() == MotionEvent.ACTION_UP) {
    
            event.setAction(MotionEvent.ACTION_CANCEL);
            super.onTouchEvent(event);
            event.setAction(MotionEvent.ACTION_DOWN);
            super.onTouchEvent(event);
            event.setAction(MotionEvent.ACTION_UP);
            return true;
        }
    
    return super.onTouchEvent(event);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-07
      • 2014-01-23
      • 2014-04-07
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多