在使用了Android 屏幕适配中推荐的适配后,我以2560×1440做了一套适配的xml,在使用过程中碰到了一些小坑:
起因:想仿照锤子手机的通讯录做一个测拉边框:测拉的宽度定为屏幕的一半,那么在使用的时候,我在xml中写了layout_width="@dimen/x720"
,也就是 720px,那么在2560×1440的手机上就是屏幕的一半了,但是实际开发中,我使用锤子手机测试,确实是屏幕的一半,在values-1920*1080
中的x720
的值就是540,OK,没有问题,但是在使用 Nexus6p 测试的时候,却发现并没有达到屏幕的一般,于是,通过计算发现在2560×1440的手机上也只有 540 px的宽度,也就是说2K屏幕的手机却读取了 1920×1080 的xml。
原因:当然并不是所有的2560×1080的手机都会这样,原因很简单,因为我使用的是 Nexus6p,这款手机只有虚拟键,没有实体键,而我也没有使得虚拟键高度的屏幕部分可用,那么APP在读取的时候读取到的屏幕高度就不是2560×1080的xml,当然这里也有我不太理解的部分,那就是,我使用 1280×720 的华为手机,华为手机基本都是有虚拟键的,而这款手机却读取了 1280×720的xml,这里我只能理解为如果不是标准的xml,那么读取的时候会遵循就近原则,获取最靠近手机分辨里的xml文件,而2560×1440可能比较特殊,他读取的是 1920×1080,这里我认为是 2K 屏幕的原因。(个人猜测,估计4K屏幕也会有这种问题)
解决:在知道了原因之后,要做的就只是计算出虚拟键的高度,然后粘贴2560×1440的xml,然后改名,我这里的实际操作计算出Nexus6p的虚拟键高度是168,然后我重新创建了一个xml – values-2392*1440
,计算虚拟键高度的代码:
/**
* 获取 虚拟按键的高度
*
* @param context
* @return
*/
public static int getBottomStatusHeight(Context context) {
int totalHeight = getDpi(context);
int contentHeight = getScreenHeight(context);
return totalHeight - contentHeight;
}
//获取屏幕原始尺寸高度,包括虚拟功能键高度
public static int getDpi(Context context) {
int dpi = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, displayMetrics);
dpi = displayMetrics.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return dpi;
}
/**
* 获得屏幕高度
*
* @param context
* @return
*/
public static int getScreenHeight(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
总结:总算告一段落,但是最终我改变了我的写法,没有像以上那样在xml中写px值,最终,我还是使用了代码去计算和设置,Android适配确实是件麻烦的事情,就算我保证了大部分机型,但是却还是无法适配小部分手机,我个人还是希望写出来的代码具有高度的适配性的,如果不是太复杂的计算那么,我想还是使用代码去做好了,这样的代码会比较高效。