完美解决 Android WebView 文本框获取焦点后自动放大问题

前几天在写一个项目时,要求在项目中嵌入一个WebView

本来很快就完成了,测试也没有问题。但发给新加坡时,他们测试都会出现文本框聚焦时,网页面会放大(他们用三星手机测试的)

网上查了好久参考他的方法加上去测试 http://www.cppblog.com/guojingjia2006/archive/2012/12/18/196429.html

下面我将原文copy过来

***************************************************************************************************************************

不同android 版本的webview底层实现有差异

今天弄了下android webview下的几个页面。原先以为android 4+把 webview的viewport属性忽略掉了。
但是今天弄了下。加了个 authorizationView.getSettings().setUseWideViewPort(true);
viewport 的几个属性重新起作用。(测试环境,4.0+的几个版本)

但是又遇到几个问题,就是html里有input的时候。获取焦点的时候,android会重新缩放到原来模式,看源码:

/**
* 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)
getContext().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);
}
if (isTextView) {
rebuildWebTextView();
if (inEditingMode()) {
imm.showSoftInput(mWebTextView, 0, mWebTextView.getResultReceiver());
if (zoom) {
didUpdateWebTextViewDimensions(INTERSECTS_SCREEN);
}
return;
}
}
// 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(this, 0);
}

从源码可以看到,webview当要弹起键盘的时候,会判定当前的缩放比例与默认大小(我测试了下,我自己的版本的默认值是1.5),
当你网页viewport设置initial-scale=0.5时,当input 获取焦点的时候,android会放大到原来模式,不是我们想要的,网上查了下相关,
有个解决方案:

wv.setOnFocusChangeListener(new View.OnFocusChangeListener() {

        @Override
public void onFocusChange(View v, boolean hasFocus) {
// TODO Auto-generated method stub
try {
Field defaultScale = WebView.class
.getDeclaredField("mDefaultScale");
defaultScale.setAccessible(true);
float _s = defaultScale.getFloat(wv);
defaultScale.setFloat(wv, scale);
float x = wv.getScale();
int i = 0;
} catch (Exception e) {
e.printStackTrace();
try {
Field defaultZoom = WebView.class
.getDeclaredField("mZoomManager");
defaultZoom.setAccessible(true);
Field defaultScale = defaultZoom.getType()
.getDeclaredField("mDefaultScale");
defaultScale.setAccessible(true);
defaultScale.setFloat(defaultZoom.get(wv), scale);
} catch (Exception ee) {
ee.printStackTrace();
}
}
}
});

但是作者碰到另外一个问题,引用自原话:

as it showed, I using reflect to find the field 'mDefaultScale' to control the WebView.
But it doesn't work on Android 4.1.1 (Google Nexus), and I catch an exception —— java.lang.NoSuchFieldException: mDefaultScale.
Then I list the fileds and found the framework source seems being changed(I can only reach a field called 'mProvider'). So how can I fix the problem (I haven't got the source yet)? Thanks for reading my question with my poor English, Thx :) PS: maybe a online framework source review website is helpful but I can't found one, if you can provide me one, it will be great. :P

完了我自己测试了,发现此方案解决不了。但是引出了另外一问题,就是不用android版本下的webview实现是不一样的,其实看代码就能看出,
原先webview有mDefaultScale字段,但是后来应该挪到mZoomManager里去了,但是我发现我手机上webview 实现和作者遇到的问题一样,只有mProvider成员,
没有mZoomManager,所以只能寻求源码,千辛万苦,终于找到
http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/android/webkit/WebViewClassic.java,
mProvider 其实类型就是WebViewClassic(自己看下源码实现),简要提下,WebProvider只是一个接口,作为WebView的一个成员,
创建时用了factory来,完了看下几个工厂类,最后是webviewclassic实例)。
 对于Jerry Bean 4.2这个版本(我一个手机就是自己刷的rom),webview的实现又换了个,所以要拿到默认缩放的成员,如下:

try {
Field defaultScale = WebView.class
.getDeclaredField("mDefaultScale");
defaultScale.setAccessible(true);
float sv = defaultScale.getFloat(authorizationView);
defaultScale.setFloat(authorizationView, xxx);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
try {
Field zoomManager;
zoomManager = WebView.class.getDeclaredField("mZoomManager");
zoomManager.setAccessible(true);
Object zoomValue = zoomManager.get(authorizationView);
Field defaultScale = zoomManager.getType().getDeclaredField("mDefaultScale");
defaultScale.setAccessible(true);
float sv = defaultScale.getFloat(zoomValue);
defaultScale.setFloat(zoomValue, xxx);
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (IllegalArgumentException e1) {
e.printStackTrace();
} catch (IllegalAccessException e1) {
e.printStackTrace();
} catch (NoSuchFieldException e1) {
e1.printStackTrace(); try {
Field mProviderField = WebView.class.getDeclaredField("mProvider");
mProviderField.setAccessible(true);
//mProviderField.getClass()
Object webviewclassic = mProviderField.get(authorizationView); Field zoomManager = webviewclassic.getClass().getDeclaredField("mZoomManager");
zoomManager.setAccessible(true);
Object zoomValue = zoomManager.get(webviewclassic);
Field defaultScale = zoomManager.getType().getDeclaredField("mDefaultScale");
defaultScale.setAccessible(true);
float sv = defaultScale.getFloat(zoomValue);
defaultScale.setFloat(zoomValue, xxx);
}catch(Exception e2)
{
e2.printStackTrace();
}
}
}

虽然可以拿到,并且设置成功,但是在我的手机上还是不能解决input 获取焦点后自动放大,
完了想了下,有个实现模式可以参考:当input 获取焦点时,js调用java设置默认放缩率,设置前保存原有值,失去焦点后重新设置原来值,不然跳转到其他页面的时候,你会发现比例不对了。:)。

因为放大后双击还是还原回原来样子。所以暂且不来纠结这个东西了。因为不同android版本的如果webview实现不一致的话,这代码就不起作用了 :)

***************************************************************************************************************************

按大神的方法测试只有在三星手机找不到 mZoomManager 这个类 所以方法还是行不通

后来又找到TV端Android WebView 文本框获取焦点后自动放大的问题(代码我就只copy部分过来了)

——————————————————————————————————————————————————————————————————————

最后经过多次尝试最后找的解决办法就是:在webview.setWebChromeClient中重写onProgressChanged方法,加入view.requestFocus();就可以让文本框得到焦点后弹出键盘,同时页面也不会被放大;

针对TV端的 webview中的网页设定,可以参考一下代码

mWebView.setWebChromeClient(new WebChromeClient()
{ @Override
public void onProgressChanged(WebView view, int newProgress)
{
// TODO Auto-generated method stub
super.onProgressChanged(view, newProgress);
view.requestFocus(); } });

重载onProgressChanged方法之后,页面缩放的问题解决了,键盘调用也正常了。

——————————————————————————————————————————————————————————————————————

摘自:http://www.myexception.cn/web/1891062.html

我加到我的代码中,发现在手机中的确有效果,但发到新加坡,得到的回复,还是同样的问题!

到此,我表示我很伤心很伤心

想想,只能用js去处理了

正当我伤心写着demo时,我老大下班了,问我走不走。我就跟他讲了我的问题。他果断去开机去了,说试试他那边能不能改(我老大是写后台端的)

问题解决了,只加了以下两句代码---------------蛋蛋的优伤

<!-- 下面两句代码是做手机适配用的 , 加上之后手机网页就会自动适配-->
<meta name="viewport" content="width=device-width">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

哦,不好意思忘了上demo了

Demo:WebViewAdapter

 

(转)完美解决 Android WebView 文本框获取焦点后自动放大有关问题的更多相关文章

  1. Xamarin Android自定义文本框

    xamarin android 自定义文本框简单的用法 关键点在于,监听EditText的内容变化,不同于java中文本内容变化去调用EditText.addTextChangedListener(m ...

  2. jquery注册文本框获取焦点清空,失去焦点赋值的简单实例

    在我们开发过程中特别是用户注册时会有一个效果,就是文本框获取焦点清空提示,如果用户没有输入信息失去焦点赋值上我们的提示语.   <html> <head> <meta h ...

  3. jquery注冊文本框获取焦点清空,失去焦点赋值

    在我们开发过程中特别是用户注冊时会有一个效果.就是文本框获取焦点清空提示,假设用户没有输入信息失去焦点赋值上我们的提示语 <html> <head> <meta http ...

  4. 转:zTree树控件扩展篇:巧用zTree控件实现文本框输入关键词自动模糊查找zTree树节点实现模糊匹配下拉选择效果

    是否可以借助于zTree实现文本框输入关键词自动模糊匹配zTree下拉树,然后选择下拉树内节点显示在文本框内且隐藏下拉树. 看到这个需求脑子里头大致已经想到了要如何实现这样一个需求,当时是限于时间问题 ...

  5. Axure实现提示文本单击显示后自动消失的效果

    Axure实现提示文本单击显示后自动消失的效果 方法/步骤     如图所示,框出的部分为提示文本(已经命名为tooltip),希望达到的效果是默认加载时不显示,点击帮助图标后显示,且2秒后自动消失. ...

  6. Android 富文本框实现 RichEditText

    Android系统自带控件没有富文本框控件,如果想写一封带格式的邮件基本上不可能,EdtiText只有默认一种格式,显示不能滿足要求,!!正好项目需要研究了一下,开发了此控件,现将一些源代码开放一下, ...

  7. Android EditText 文本框实现搜索和清空效果

    前言 本文实现的效果:文本框输入为空时显示输入的图标:不为空时显示清空的图标,此时点击清空图标能清空文本框内输入文字. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnbl ...

  8. android自定义文本框,后面带清空按钮

    android常见的带清空按钮的文本框,获得焦点时如果有内容则显示,否则不显示 package com.qc.health.weight; import com.qc.health.R; import ...

  9. 完美解决Android SDK Manager无法更新

    由于国内的各种屏蔽现在Android SDK Manager出现无法更新或更新太慢,如下方法可完美解决此问题 1. 打开..\Android\sdk\SDK Manager.exe  2.

随机推荐

  1. Highcharts 树状图(Treemap)

    Highcharts 树状图(Treemap) 树状图 series 配置 设置 series 的 type 属性为 treemap ,series.type 描述了数据列类型.默认值为 " ...

  2. linux---进程,(rpm,yum)软件包

      3) 为新加的硬盘分区,一个主分区大小为5G,剩余空间给扩展分区,在扩展分区上划分1个逻辑分区,大小为5G fdisk -l fdisk /dev/sdb p 查看 n 新建    p  主分区 ...

  3. oracle 修改字符集 修改为ZHS16GBK

    oracle数据库的字符集更改 A.oracle server 端 字符集查询 select userenv('language') from dual 其中NLS_CHARACTERSET 为ser ...

  4. Element-UI 实现下拉树

    组件调用 <template> <!-- 行模式 --> <el-form inline> <el-form-item label="inline ...

  5. C#学习历程(四)[实际问题]

    >>无法直接启动带有”类库输出类型”的项目 在编辑界面的右侧会出现[解决方案资源管理器],里面显示我们的程序项目和所有代码文件. 右键点击项目,在右键菜单中选择[属性] 一般导致该问题都是 ...

  6. LeetCode OJ:Reorder List(重序链表)

    Given a singly linked list L: L0→L1→…→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do thi ...

  7. maven手动添加jar(转)

    Maven 手动添加 JAR 包到本地仓库 原文链接:http://www.blogjava.net/fancydeepin/archive/2012/06/12/380605.html Maven ...

  8. SQL语句中各个部分的执行顺序(转)

    原文链接:http://www.tuicool.com/articles/fERNv2 写在前面的话:有时不理解SQL语句各个部分执行顺序,导致理解上出现偏差,或者是书写SQL语句时随心所欲,所以有必 ...

  9. eclipse ndk 配置和简单开发demo

    记录下以备忘: android开发的各种资源国内镜像 http://www.androiddevtools.cn/ 前端时间尝鲜用android stuido1.5开发了个android的小项目,发现 ...

  10. python中sort()与sorted()的区别

    Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列 一,最简单的排序 1.使用sort排序 my_list = [3 ...