dlewis22
dlewis22

Reputation: 111

Is there a way to disable the zoom feature on input fields in webview?

When a user clicks in an input field or textarea, the application zooms in. Is there a simple way to disable it?

Currently have the meta tag:

meta name="viewport" content="width=device-width; height=device-height; initial-scale=1.0; maximum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi;"

Everything looks great till I look at it on a device with Android 2.2 Specifically HTC Evo 4G.

Upvotes: 11

Views: 21912

Answers (10)

leemeun smith
leemeun smith

Reputation: 9

In WebViewClassic.java, displaySoftKeyboard zooms in and pans if the actual scale is less than the default scale. There is a field in the WebWiew.class mDefaultScale float the source code shows that when you display softkeyboard the mActualScale will change.

So making sure that mActualScale is >= mDefaultScale should prevent the panning and rescaling. (Below is source code for WebView.java from the grepcode site -- which is no longer running.)

private void  displaySoftKeyboard(boolean isTextView) {
     InputMethodManager imm = (InputMethodManager)
     getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (isTextView) {
            if (mWebTextView == null) return;
            imm.showSoftInput(mWebTextView, 0);

            if (mActualScale < mDefaultScale) {

                // bring it back to the default scale so that user can enter

                // text.
                mInZoomOverview = false;
                mZoomCenterX = mLastTouchX;
                mZoomCenterY = mLastTouchY;
                // do not change text wrap scale so that there is no reflow
                setNewZoomScale(mDefaultScale, false, false);
                adjustTextView(false);
            }
        }

        else { // used by plugins
            imm.showSoftInput(this, 0);
        }

    }

Code from googleSource--WebViewClassic.java in frameworks/base/core/java/android/webkit/WebViewClassic.java (for JellyBean api 17) shows similar functionality:

/**
 * Called in response to a message from webkit telling us that the soft
 * keyboard should be launched.
 */
private void displaySoftKeyboard(boolean isTextView) {
    InputMethodManager imm = (InputMethodManager)
            mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    // bring it back to the default level scale so that user can enter text
    boolean zoom = mZoomManager.getScale() < mZoomManager.getDefaultScale();
    if (zoom) {
        mZoomManager.setZoomCenter(mLastTouchX, mLastTouchY);
        mZoomManager.setZoomScale(mZoomManager.getDefaultScale(), false);
    }
    // Used by plugins and contentEditable.
    // Also used if the navigation cache is out of date, and
    // does not recognize that a textfield is in focus.  In that
    // case, use WebView as the targeted view.
    // see http://b/issue?id=2457459
    imm.showSoftInput(mWebView, 0);
}

Upvotes: 0

Luu Thanh Tuan
Luu Thanh Tuan

Reputation: 1

Finally, I found a solution for my real-world project.

- MainActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    WebView mWebView = (WebView) findViewById(R.id.webview);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        mWebView.setOnFocusChangeListener(new MyOnFocusChangeListener(getScale()));
    }
    Log.i(MainActivity.class.getSimpleName(), "getScale: " + getScale());
}

/**
 * Calculate the scale that we need to use manually.
 *
 * @return the scale that we need
 */
private float getScale() {
    DisplayMetrics display = this.getResources().getDisplayMetrics();
    int width = display.widthPixels;
    Float val = Float.valueOf(width) / Float.valueOf(Constants.PAGE_WIDTH);
    return val.floatValue();
}

- MyOnFocusChangeListener.java

public class MyOnFocusChangeListener implements View.OnFocusChangeListener {

    protected float mScale;

    public MyOnFocusChangeListener(float scale) {
        mScale = scale;
    }

    /**
     * Implement this method because we want to apply scale when focus changed.
     * @param v the View we want to apply scale when focus changed.
     * @param hasFocus has a focus or not.
     */
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            // We must try all cases because mDefaultScale will change on different versions of Android.
            try {
                Field defaultScale = WebView.class.getDeclaredField("mDefaultScale");
                defaultScale.setAccessible(true);
                defaultScale.setFloat(v, mScale);
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                try {
                    Field zoomManager;
                    zoomManager = WebView.class.getDeclaredField("mZoomManager");
                    zoomManager.setAccessible(true);
                    Object zoomValue = zoomManager.get(v);
                    Field defaultScale = zoomManager.getType().getDeclaredField("mDefaultScale");
                    defaultScale.setAccessible(true);
                    defaultScale.setFloat(zoomValue, mScale);
                } catch (SecurityException e1) {
                    e1.printStackTrace();
                } catch (IllegalArgumentException e1) {
                    e.printStackTrace();
                } catch (IllegalAccessException e1) {
                    e.printStackTrace();
                } catch (NoSuchFieldException e1) {
                    try {
                        Field mProviderField = WebView.class.getDeclaredField("mProvider");
                        mProviderField.setAccessible(true);
                        Object webviewclassic = mProviderField.get(v);
                        Field zoomManager = webviewclassic.getClass().getDeclaredField("mZoomManager");
                        zoomManager.setAccessible(true);
                        Object zoomValue = zoomManager.get(webviewclassic);
                        Field defaultScale = zoomManager.getType().getDeclaredField("mDefaultScale");
                        defaultScale.setAccessible(true);
                        defaultScale.setFloat(zoomValue, mScale);
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                }
            }
        }
    }
}

Upvotes: 0

Alex Vaz de Moraes
Alex Vaz de Moraes

Reputation: 11

Just set in manifest:

android:windowSoftInputMode="adjustPan"

Upvotes: 1

jeff wang
jeff wang

Reputation: 41

webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.MEDIUM); 

This method was deprecated in API level 19.

this works in the last android versions 4.4.2.

webView.setInitialScale(0);//default,no zoom
webView.getSettings().setSupportZoom(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setLoadWithOverviewMode(false);
webView.getSettings().setUseWideViewPort(false);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);

Upvotes: 2

WindsorAndy
WindsorAndy

Reputation: 247

I know this thread is ancient history but I had the scaling issue with the virtual keyboard and eventually found the solution at this link:

http://rickluna.com/wp/2012/02/set-app-scaling-in-phonegap-android/

Add these lines to the app's java source

appView.getSettings().setSupportZoom(false);
appView.getSettings().setUseWideViewPort(false);
WebSettings ws = appView.getSettings();
ws.setDefaultZoom(WebSettings.ZoomDensity.MEDIUM);
appView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.MEDIUM);
appView.setInitialScale(0);
ws.setSupportZoom(false);
ws.setBuiltInZoomControls(false);
ws.setUseWideViewPort(false);

I changed MEDIUM to FAR which keeps the screen at the original 1.0 magnification.

Hopefully that saves other people some searching

Upvotes: 0

Frederik Wordenskjold
Frederik Wordenskjold

Reputation: 10221

Isn't this simply a text-size adjust issue?

body{ 
    -webkit-text-size-adjust:none; 
}

Upvotes: 1

Ricardo BErzal
Ricardo BErzal

Reputation: 11

I found the answer, at least for me. It works on HTC desire and Sansung 3 low res.

  • Remove the viewport meta tags from the HTML.

  • In java apply the solution that can be found here.

    this.appView.getSettings().setSupportZoom( true ); //Modify this
    this.appView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);//Add this
    

    Remember to test if WebSettings.ZoomDensity.FAR is available to your SDK version (7 and above).

Upvotes: 1

standup75
standup75

Reputation: 4814

Here is how I solved that:

On all my pages I have:

<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio:0.75)" href="css/ldpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio:1)" href="css/mdpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio:1.5)" href="css/hdpi.css" />
<meta name="viewport" content="target-densitydpi=device-dpi" />

On the pages with input fields, I have:

<link rel="stylesheet" media="screen" href="css/mdpi.css" />
<meta name="viewport" content="target-densitydpi=medium-dpi" />

So, I don't benefit from hdpi on the forms, but at least it does not zoom in

Upvotes: 0

Mike P
Mike P

Reputation: 2877

I've got the same problem (on an HTC Incredible), and haven't found a good fix yet. But, one thing I did notice that if you use the Google mobile site (http://google.com/m) you don't get this behavior, I'm trying to figure out why that's the case.

I've tried all the fixes mentioned on stackoverflow that I could find, including on this thread and nothing that I've found works so far.

One crappy fix I've found the works is to set the initial scale to 150 (1.5X) and then scale your website accordingly then you also don't get this zooming behavior - maybe because it wants a zoom level of 1.5X when you click on a text input and if you're already at that zoom level then nothing happens? But, this feels super hacky and probably isn't robust across all phones.

Upvotes: 0

TheisEgeberg
TheisEgeberg

Reputation: 31

I messed around with this alot.

You have to have different solutions for different screen sizes and phones, done serverside.

This works for a HTC desire for instance:

<meta content='True' name='HandheldFriendly' />
<meta content='width=640px; initial-scale=0.50; maximum-scale=0.50;minimum-scale=0.50;' name='viewport' />
<meta name="viewport" content="width=640px" />

This is for an iphone:

<meta name="viewport" content="width=640px,user-scalable=0" />

Upvotes: 3

Related Questions