Android7.0以上可以在系统是调整显示大小,调整显示大小其实是改变了系统的densityDpi的值,由于h5界面是用的px为单位,所以densityDpi一旦改变,h5界面就会受到影响,控件会跟随系统放大或缩小,为了禁止h5跟随系统显示大小进行缩放,最初的设想是使用网上找到的办法将系统的densityDpi的值给恢复成系统默认大小。
public static void setDefaultDisplay(Context context) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
Configuration origConfig = context.getResources().getConfiguration();
//获取手机出厂时默认的densityDpi【注释1】
origConfig.densityDpi = getDefaultDisplayDensity();
// origConfig.fontScale = 1.0f;
Log.d("zyy", "densityDpi: " + origConfig.densityDpi);
context.getResources().updateConfiguration(origConfig, context.getResources().getDisplayMetrics());
}
}
public static int getDefaultDisplayDensity() {
try {
Class clazz = Class.forName("android.view.WindowManagerGlobal");
Method method = clazz.getMethod("getWindowManagerService");
method.setAccessible(true);
Object iwm = method.invoke(clazz);
Method getInitialDisplayDensity = iwm.getClass().getMethod("getInitialDisplayDensity", int.class);
getInitialDisplayDensity.setAccessible(true);
Object densityDpi = getInitialDisplayDensity.invoke(iwm, Display.DEFAULT_DISPLAY);
return (int)densityDpi;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
但是修改后可以看到虽然原生控件恢复了正常大小,但是h5的控件还是跟随系统调整了大小。
因此想到是否可以修改webview的配置来控制h5页面缩放,翻了webview的方法找到了setInitialScale方法,setInitialScale可以设置webview初始缩放比例,受setUseWideViewPort和setLoadWithOverviewMode两个函数影响
/**
* Sets the initial scale for this WebView. 0 means default.
* The behavior for the default scale depends on the state of
* {@link WebSettings#getUseWideViewPort()} and
* {@link WebSettings#getLoadWithOverviewMode()}.
* If the content fits into the WebView control by width, then
* the zoom is set to 100%. For wide content, the behavior
* depends on the state of {@link WebSettings#getLoadWithOverviewMode()}.
* If its value is true, the content will be zoomed out to be fit
* by width into the WebView control, otherwise not.
*
* If initial scale is greater than 0, WebView starts with this value
* as initial scale.
* Please note that unlike the scale properties in the viewport meta tag,
* this method doesn't take the screen density into account.
*
* @param scaleInPercent the initial scale in percent
*/
public void setInitialScale(int scaleInPercent) {
其中scaleInPercent这个参数不是网上说的setInitialScale(50),就是缩放50%,setInitialScale(100)也不是不缩放,人家注释里明明写着0才是不缩放,不知道网上结论是怎么得出来的。
通过WebViewClient的这个监听scale的函数:
public void onScaleChanged(WebView view, float oldScale, float newScale)
当我设置setInitialScale(300)时,会调用onScaleChanged()方法,通过这个方法获取到oldScale是2.625,newScale是3.00,3.00这值是我设的,2.625哪来的,这值眼熟啊
我使用的手机默认densityDpi = 420,dip = 420/160 = 2.625,嗯就是这个值了,其实就是density这个值
所以要想把h5页面还原默认大小就简单了,setInitialScale(262)就成了。
//不跟随系统字体大小
settings.setTextZoom(100);
//不跟随系统显示大小
float defaultDensity = DeviceUtils.getDefaultDisplayDensity();
float scale = (defaultDensity/160) * 100;
webView.setInitialScale((int)scale);