2012-05-03 2 views
1

Я показываю веб-страницу в Android WebView. Страницу нужно масштабировать, чтобы она соответствовала доступной ширине 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); 

Это работает отлично, за исключением одной проблемы: дважды вкладка вызывает переключение между обзором режиме и по умолчанию.
Есть ли способ отключить эту функцию?

Btw: Я не могу рассчитать шкалу в коде, потому что загруженные страницы могут иметь разные размеры, о которых я не знаю заранее. Я также уже проверил исходный код 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 г и возвращает истину на двойное нажатие событий:

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 
    } 

Наконец Override OnTouchEvent вашего WebView и пусть он проходит через события к детектору жест, как это:

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

Это работает довольно хорошо в целом, но есть 1 основной недостаток этого решения: некоторые события, которые не идентифицируются как события DoubleTap, могут привести к увеличению масштаба вашего веб-представления.

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:

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

Override метод 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); 
} 
Смежные вопросы