2012-05-03 93 views
1

我在Android WebView中顯示網頁。該頁面需要縮放以適應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的源代碼,但沒有看到任何我可以覆蓋或更改的東西。

回答

0

你可以寫你自己的WebView實現implemting 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. 
} 

現在實現OnGestureListene中的方法r和上雙擊事件返回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 
    } 

最後重寫網頁視圖中的onTouchEvent,讓它穿過事件姿態探測器是這樣的:

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

這個工作通常不錯,但有此解決方案存在1個基本缺陷:某些未被識別爲DoubleTap事件的事件可能會導致您的webview縮放。

I'm仍在爲一個解決方案,並會張貼我的進步在這裏: WebView getting rid of double tap zoom.

+0

Thx,看起來很有希望。我將接受它作爲答案而不進行測試。我做了一個黑客,我完全禁用了縮放功能,將WebView傳遞給了HTML,並且適合JavaScript內的內容。不是很好,但它工作。 – SimonSays

0

一般來說,改變一個已知的API並不是好的做法。你應該找到一個不同的方式來做到這一點,也許longClick。不管怎麼說,看看this similar question

+0

雙標籤是不是我補充。它被嵌入到WebView中,所以我無法改變它。無論如何,我不想添加它,我想禁用它。 – SimonSays

+0

正如我所說的,在本地用戶界面中禁用nuilt是不好的做法 – thepoosh

0

如果可能的話,在你的HTML代替靜態的meta標籤:

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