完美解决 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 textboolean 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=2457459imm.showSoftInput(this, 0);}

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

wv.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {// TODO Auto-generated method stubtry {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()
{@Overridepublic void onProgressChanged(WebView view, int newProgress){// TODO Auto-generated method stubsuper.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

 

转载于:https://www.cnblogs.com/antyi/p/5217559.html

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

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

    前几天在写一个项目时,要求在项目中嵌入一个WebView 本来很快就完成了,测试也没有问题.但发给新加坡时,他们测试都会出现文本框聚焦时,网页面会放大(他们用三星手机测试的) 网上查了好久参考他的方法 ...

  2. 文本框获取焦点后出现的边框,怎么去掉

    文本框获取焦点后出现的边框,怎么去掉 其实这个不是边框,而是轮廓!用CSS 去掉轮廓就行了! outline:none 属性定义及使用说明 outline(轮廓)是绘制于元素周围的一条线,位于边框边缘 ...

  3. 开发笔记:解决安卓GestureOverlayView手势和ListView点击事件、文本框获取焦点冲突的问题

    要解决这个问题,首先要弄清楚几个问题: 1.onThouch事件的触发原理是怎样的? 2.GestureOverlayView的绘制手势的事件是在什么时候触发的? 3.父子嵌套的控件触发事件的顺序是怎 ...

  4. android studio try again,完美解决Android Studio在gradle上的各种问题

    原标题:完美解决Android Studio在gradle上的各种问题 题记: 看到很多人都来读这篇文章,说明很多人都有遇到这个问题,文章质量不是很高,感觉我自己都有些看不懂了,因此来更新一下,希望可 ...

  5. android studio crashlytics,完美解决Android Studio集成crashlytics后无法编译的问题

    问题描述: 在用fabric集成后编译出现如下错误, Error:Cause: hostname in certificate didn't match: != OR OR build.gradle部 ...

  6. html在文本框选中后在表格中选中,excel表格出现文本框的解决方法步骤

    在Excel中如果出现了很多文本框而不是自己需要的,那这些文本框可以删除的.下面是学习啦小编带来的关于excel表格出现文本框的解决方法,希望阅读过后对你有所启发! excel表格出现文本框的解决方法 ...

  7. android webview 设置cookie时间,解决Android webview设置cookie和cookie丢失的问题

    Android页面嵌套了一个h5,H5页面内部有用户登陆页面,发现h5页面的登陆功能无法使用,一直登陆失败.和web那边商量一会,发现js写入的cookie丢失了.所有需要Android这边在重写写入 ...

  8. android打开app白色页面,完美解决Android App启动页有白屏闪过的问题

    应用启动的时候有短暂的白屏,如图: 可以通过设置theme的方式来解决 @color/colorPrimary @color/colorPrimaryDark @color/colorAccent t ...

  9. android 通知过滤,冰箱 IceBox 开发者新作,完美解决 Android 通知过滤问题的 APP

    原标题:冰箱 IceBox 开发者新作,完美解决 Android 通知过滤问题的 APP 在用 Android 手机时,我们会有一些应用没办法不用,但是又想让它没有不用这时候就像卸载那样安安静静地待在 ...

最新文章

  1. 全球缺芯大潮中,以软代硬能否另辟蹊径?
  2. 【阿里云总监课第四期】时髦的云原生应用怎么写?
  3. (0095)iOS开发之本地文件预览的三种方法(3)
  4. 3.1集合相关知识点
  5. .NET c# Color对象的使用介绍(转)
  6. 重新学习Spring一--Spring在web项目中的启动过程
  7. 借助Java 8和lambdas,可以一起使用AssertJ和Awaitility
  8. 加载的图片还会有未来吗?
  9. 数据结构基础(17) --二叉查找树的设计与实现
  10. 同态加密实现数据隐私计算,能让你的小秘密更加秘密
  11. Spring Boot 2.1.5(25)---SpringBoot基于WebFlux注解
  12. [渝粤教育] 浙江大学 2021 2022秋数码摄影技术 参考 资料
  13. MySQL的初次使用
  14. heapsort(Java)(最小堆)
  15. react 中event 的处理方式
  16. Mac将Wps本地文件备份到云端
  17. 一文详解蒙特卡洛(Monte Carlo)法及其应用
  18. 大二学生基于Html+Css+javascript的网页制作——动漫设计公司响应式网站模板 (10个页面)
  19. js控制表格实时编辑
  20. ETA4322耐压30V,线性充1000mA,充电电流可调,双灯指示

热门文章

  1. 使用susy内置混合宏异常:Undefined mixin ‘at-breakpoint‘
  2. 将照片按顺序制作成PDF
  3. 为更美好的商业生态,淘系技术全力以赴
  4. android 10.0状态栏显示电量百分比
  5. elasticsearch Analyzer
  6. 向日葵远程软件连不上服务器
  7. 老猿学5G扫盲贴:与用户和终端相关的名词UE、SUPI、GPSI、PEI
  8. 如何处理项目遗留问题?
  9. 谁是K歌之王? 爱唱/唱吧全面对比
  10. mac和windows多功能的乐谱格式批量转换器,支持midi、mscz、xml...转mp3、xml、ove、bmw、pdf等