(二十四)屏幕适配的基本概念
1、
屏幕大小 :物理屏幕的大小,看屏幕的对角线。
分辨率 :实际上是像素的总和。1280*720
dpi :屏幕密度(density )。(每英寸所展示的像素)
2、
hdpi :放480*800分辨率的图片 ~240dpi
ldpi :320*240 ~120dpi
mdpi : 320*480 ~160dpi (参照物)
xhdpi: 1280*720 ~320dpi
ldpi、mdpi、hdpi、xhdpi缩放比例
l :m :h :x
3:4:6:8
据px = dip * density / 160,则当屏幕密度为160时,px = dip
当屏幕密度为320时,px=2dip
当屏幕密度为240时,px=1.5dip;
3、
480*800 :小分辨率往大分辨率兼容,填充屏幕的时候,会拉伸,出现模糊现象,不填充,不拉伸。
大分辨率往小分辨率兼容,可能会出现程序崩溃。一般切图切 hdpi (放480*800分辨率的图片 ),只有那些填充屏幕的图片才切一套
(1280*720)放在xhdpi文件中。在Android的设计过程中,为了适配不同的手机分辨率,图片大多需要拉伸或者压缩,这样就出现了可以任意调整
大小的一种图片格式“.9.png”。这种图片是用于Android开发的一种特殊的图片格式,它的好处在于可以用简单的方式把一张图片中哪些区域可以
拉伸,哪些区域不可以拉伸设定好,同时可以把显示内容区域的位置标示清楚。
4、屏幕适配 的方法:
4.1、根据屏幕不同分辨率定义不同的布局文件,如下图 所示:
4.2、根据屏幕不同分辨率定义不同尺寸,如下图所示:
4.3、在代码中根据屏幕的尺寸,动态的设置布局
//获取屏幕高宽 DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); windowsHeight = metric.heightPixels; windowsWight = metric.widthPixels; //动态改变布局 LinearLayout production_factory = (LinearLayout)findViewById(R.id.production_factory); LayoutParams params = production_factory.getLayoutParams(); params.height = windowsHeight / 2; production_factory.setLayoutParams(params);
4.4利用属性layout_weight来设置。
4.5 虽然说dp可以去除不同像素密度的问题,使得1dp在不同像素密度上面的显示效果相同,但是还是由于Android屏幕设备的多样性,如果使用dp来作为度量单位,并不是所有的屏幕的宽度都是相同的dp长度。当然,我们尽量使用match_parent和wrap_content,尽可能少的用dp来指定控件的具体长宽,再结合上layout_weight,大部分的情况我们都是可以做到适配的。设置不同的ScaleType会得到不同的显示效果,一般情况下,设置为centerCrop能获得较好的适配效果。
5、在代码中使用屏幕密度进行适配
在xml布局文件中,我们既可以设置px,也可以设置dp(或者dip)。一般情况下,我们都会选择使用dp,这样可以保证不同屏幕分辨率的机器上布局一致。但是在代码中,如何处理呢?很多控件的方法中都只提供了设置px的方法,例如setPadding,并没有提供设置dp的方法。这个时候,如果需要设置dp的话,就要将dp转换成px了。
以下是一个应用类,方便进行px和dp之间的转换。
public class DimenUtil { private static Typeface typeface; // 根据手机的分辨率从 dp 的单位转成为 px(像素) public static float dp2px(float dp, Context context) { final float scale = context.getResources().getDisplayMetrics().density; return dp * scale + 0.5f; } // 获得屏幕尺寸 public static Point getScreenSize(Activity activity) { Point size = new Point(); activity.getWindowManager().getDefaultDisplay().getSize(size); return size; } // 根据手机的分辨率从 px(像素) 的单位 转成为 dp public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } // 根据手机的分辨率从 sp 的单位 转成为 px(像素) public static float sp2px(float sp, Context context) { final float scale = context.getResources().getDisplayMetrics().scaledDensity; return sp * scale; } /** * 将px值转换为sp值,保证文字大小不变 * * @param pxValue * @param fontScale * (DisplayMetrics类中属性scaledDensity) * @return */ public static int px2sp(Context context, float pxValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); } public static int dpToPx(Resources res, int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics()); } public static int spToPx(Resources res, int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, dp, res.getDisplayMetrics()); } }
6、尺寸标注的时候到底用哪个分辨率下的?
如果要兼顾IOS,又只一套尺寸,现在可以考虑1080*1920会好点。
1080P的刚好可以把Android和iPhone分辨率统一,这个分辨率算是Android标准分辨率之一,低分辨率也可以按照这个分辨率缩小尺寸,一般系统可以帮我们处理一些问题。刚好iPhone 6plus也是用这个分辨率,iOS那边对分辨率处理比较友好。系统会帮忙优化,像Android,对不同分辨率采用不同分辨率图片的时候,都是可以按比例放大缩小的。因为关键一点不在于分辨率差多少,而是长宽比。也可以参考一下iOS的意见,一般我了解的就这样,iOS要是不要求高精度的图片,都可以用一个分辨率进行适配。,因为即使用iPhone6的尺寸,在Android上使用,只要不精确到10个像素的精度,一般也是没问题。