I read many tickets on the topic of Zooming in WebViews and didnt came to an answer for my case.
Here´s my setup:
I´m using a custom webview with generally these settings:
getSettings().setBuiltInZoomControls(false);
getSettings().setSupportZoom(false);
getSettings().setUseWideViewPort(true);
getSettings().setLoadWithOverviewMode(true);
Let me note right here that i depend on OverviewMode and as well on WideViewPort to Scale my WebView.
I´m also Overriding my OnTouchEvent and and delegate all suitable events to an Gesture detector:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) return true;
return super.onTouchEvent(event);
}
Here is its listeners implementation which is intercepting all doubleTap events:
@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;
}
Also i overrode these 2 WebView methods related to zoom:
@Override
public boolean zoomIn() {
return true;
}
@Override
public boolean zoomOut() {
return true;
}
Notherless of all these options a certain tap frequence will cause my webview to zoom in/out. I havent found an option that disables this kind of zooming, the MotionEvent for this Zoom doesnt seem to be applicable for the GestureDetector and the override zoomIn() zoomOut() methods have no effect either.
Can anyone help me out with a way to avoid this double tap zoom behaivior of WebView?
In future versions of Chrome for Android, the double tap will be removed when you have a viewport set. If you want to disable it for stable today, you will need to set user-scalable=no in your viewport. This will disable zooming (which may be bad for accessibility) but should allow you to get all touch events.
Tap anywhere on the screen, except the keyboard or navigation bar. Drag 2 fingers to move around the screen. Pinch with 2 fingers to adjust zoom. To stop magnification, use your magnification shortcut again.
There are two methods to achieve your goal:
Method 1
Implement the GestureDetector.OnDoubleTapListener
like this:
@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;
}
and attach it to your GestureDetector
like this:
gestureDetector.setOnDoubleTapListener(this);
Method 2
You can also use the WebSettings.setUseWideViewPort(false);
and calculate the size of your view manually.
These methods should help you to achieve non-zoomable webviews that display everything.
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;
}
There's a fantastic solution for your issue, based on Javascript (so you'll have to have access to the HTML/JS code in the remote side, if it's the case).
Using the FastClick library, all you need to do is to add the .js file and then call it:
<script type="application/javascript" src="fastclick.js"></script>
<script language="javascript">
window.addEventListener('load', function() {
FastClick.attach(document.body);
}, false);
</script>
This will get rid of the double tap zoom, and there's still (in my opinion) a huge bonus: all taps get 0.3 seconds faster, due to the fact the system doesn't have to wait anymore for a double tap! Check this example on Android to see the difference: Practical Example
Well, I don't know if this solution will fit in your case, but it was a perfect solution for my Webview projects. Hope it helps!
ps1: you have to add the code above in all pages and frames
ps2: the pinch zoom will keep working normally
You need to override OnTouchListener on your WebView by
wv.setOnTouchListener(this);
and inside method onTouch just check that if it detect double tab then ignore the zoom in webview by force to return true
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
onTouchEvent(event);
if (doubletab)
return true;
return false;
}
You can see full code like this: 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;
}
}
and 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>
don't forget to add permission in manifest.xml
<uses-permission android:name="android.permission.INTERNET" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With