10

Zooming in WebViews のトピックに関する多くのチケットを読みましたが、私の場合は答えがありませんでした。

これが私のセットアップです:

一般的に次の設定でカスタム Web ビューを使用しています。

getSettings().setBuiltInZoomControls(false);
getSettings().setSupportZoom(false);
getSettings().setUseWideViewPort(true);
getSettings().setLoadWithOverviewMode(true);

ここで、WebView をスケーリングするために、OverviewMode と WideViewPort に依存していることに注意してください。

また、OnTouchEvent をオーバーライドし、すべての適切なイベントをジェスチャー検出器にデリゲートします。

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

以下は、すべての doubleTap イベントをインターセプトするリスナーの実装です。

  @Override
  public boolean onDoubleTapEvent(MotionEvent e) {
    // Do nothing! 
    return true;
  }

  @Override
  public boolean onDoubleTap(MotionEvent e) {
    // Do nothing! 
    return true;
  }

  @Override
  public boolean onSingleTapConfirmed(MotionEvent e) {
    // Do nothing! 
    return true;
  }

また、ズームに関連するこれらの 2 つの WebView メソッドをオーバーライドしました。

  @Override
  public boolean zoomIn() {
    return true;
  }

  @Override
  public boolean zoomOut() {
    return true;
  }

これらすべてのオプションに関係なく、特定のタップ頻度により、Web ビューがズームイン/ズームアウトします。この種のズームを無効にするオプションは見つかりませんでした。この Zoom の MotionEvent は GestureDetector に適用できないようで、オーバーライド zoomIn() zoomOut() メソッドも効果がありません。

WebView のこのダブルタップ ズーム動作を回避する方法を教えてくれる人はいますか?

4

6 に答える 6

7

目標を達成するには、次の 2 つの方法があります。

方法 1

GestureDetector.OnDoubleTapListener次のように実装します。

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
  return false; //Nothing
}

@Override
public boolean onDoubleTap(MotionEvent e) {
  //Indicates that this implementation has handled the double tap.
  return true;
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
  //Indicates that this implementation has handled the double tap.
  return true;
}

そしてそれをあなたのように添付してくださいGestureDetector

gestureDetector.setOnDoubleTapListener(this);

方法 2

WebSettings.setUseWideViewPort(false);を使用して、ビューのサイズを手動で計算することもできます。

これらの方法は、すべてを表示するズーム不可の Web ビューを実現するのに役立ちます。

public int getWindowWidth(Activity activity) {
  Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
  Point size = new Point();
  display.getSize(size);
  int width = size.x;
  return width;
}

public int getInitialScale(Activity activity, int websiteWidth) {
  return (getWindowWidth(activity) / websiteWidth) * 100;
}
于 2012-09-07T11:26:41.127 に答える
2

あなたの問題には、Javascript に基づいた素晴らしい解決策があります (その場合、リモート側で HTML/JS コードにアクセスする必要があります)。

FastClick ライブラリを使用して、.js ファイルを追加して呼び出すだけです。

<script type="application/javascript" src="fastclick.js"></script>

<script language="javascript">

window.addEventListener('load', function() {
    FastClick.attach(document.body);
}, false);

</script>

これにより、ダブルタップ ズームがなくなりますが、(私の意見では) 大きなボーナスがまだあります。システムがダブルタップを待つ必要がないため、すべてのタップが 0.3 秒速くなります! 違いを確認するには、Android で次の例を確認してください

このソリューションがあなたのケースに当てはまるかどうかはわかりませんが、私の Webview プロジェクトにとっては完璧なソリューションでした。それが役に立てば幸い!

ps1: すべてのページとフレームに上記のコードを追加する必要があります

ps2: ピンチ ズームは正常に機能し続けます。

于 2014-02-28T05:22:38.393 に答える
1

WebView で OnTouchListener をオーバーライドする必要があります。

    wv.setOnTouchListener(this);

メソッドonTouch内で、ダブルタブが検出された場合は、Webビューのズームインを強制的に無視してtrueを返すことを確認するだけです

@Override
public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub
    onTouchEvent(event);

    if (doubletab)
        return true;

    return false;
}

次のような完全なコードを見ることができます: MainActivity.java

package com.example.testwebview;

import android.os.Bundle;
import android.app.Activity;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.OnTouchListener;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnGestureListener, OnTouchListener, GestureDetector.OnDoubleTapListener
{

    TextView tv;
    WebView wv;
    GestureDetector gd;

    boolean doubletab = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        gd = new GestureDetector(this);

        setContentView(R.layout.activity_main);

        tv = (TextView)findViewById(R.id.textView1);
        wv = (WebView)findViewById(R.id.webView1);

        WebSettings setting = wv.getSettings();
        setting.setBuiltInZoomControls(false);
        setting.setSupportZoom(false);
        setting.setUseWideViewPort(true);
        setting.setLoadWithOverviewMode(true);

        wv.setOnTouchListener(this);
        wv.loadUrl("http://www.sanook.com");
    }
    @Override
    public boolean onDoubleTap(MotionEvent arg0) {
        tv.setText("double tap");
        doubletab = true;
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent arg0) {
        tv.setText("double tap event");
        doubletab = true;
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent arg0) {
        tv.setText("single tap confirm");
        doubletab = false;
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent me)
    {
        return gd.onTouchEvent(me);
    }

    @Override
    public boolean onDown(MotionEvent arg0) {
        tv.setText("down");
        doubletab = false;
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
            float arg3) {
        tv.setText("fling");
        doubletab = false;
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void onLongPress(MotionEvent arg0) {
        tv.setText("long press");
        doubletab = false;
        // TODO Auto-generated method stub

    }

    @Override
    public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
            float arg3) {
        tv.setText("scroll");
        doubletab = false;
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void onShowPress(MotionEvent arg0) {
        // TODO Auto-generated method stub
        tv.setText("show press");
        doubletab = false;

    }


    @Override
    public boolean onSingleTapUp(MotionEvent arg0) {
        // TODO Auto-generated method stub
        tv.setText("single tab up");
        doubletab = false;
        return false;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        onTouchEvent(event);

        if (doubletab)
            return true;

        return false;
    }
}

および activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="TextView" />

    <WebView
        android:id="@+id/webView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView1" />

</RelativeLayout>

manifest.xml に権限を追加することを忘れないでください

<uses-permission android:name="android.permission.INTERNET" />
于 2012-09-11T04:50:05.607 に答える
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:34:29.133 に答える
-3

onDoubleTapEventonDoubleTapの戻り値をfalseにしてみてください。

@Override
  public boolean onDoubleTapEvent(MotionEvent e) {
    // Do nothing! 
    return false;
  }

  @Override
  public boolean onDoubleTap(MotionEvent e) {
    // Do nothing! 
    return false;
  }
于 2012-09-06T14:03:34.887 に答える