1

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

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

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

爪哇:

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 的源代码,但没有看到任何可以覆盖或更改的内容。

4

3 回答 3

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

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

我仍在为此研究解决方案,并将在此处发布我的进展: WebView 摆脱双击缩放。

于 2012-09-10T11:57:12.533 回答
0

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

不管怎样,看看这个类似的问题

于 2012-05-03T05:48:57.680 回答
0

如果可能,请替换 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);
}
于 2015-02-11T12:50:11.470 回答