一、基础概念了解
1、屏幕尺寸
屏幕对角线的长度,单位英寸,1英寸=2.54cm
2、屏幕分辨率
屏幕横向和众向像素点数 单位px 1px=1物理像素,现在一般以1920*1080为基准
3、屏幕像素密度dpi(Dots Per Inch)
每英寸上的像素点数,单位dpi,与像素无关的单位;像素密度与屏幕尺寸,屏幕分辨率有直接的关系
标准屏幕像素密度(mdpi) ,每英寸长度上有160个像素点(160dpi)
像素密度是清晰度很重要的一个概念:即像素密度越高(dpi)代表显示屏能够以更高的密度显示图像。当然,显示的密度越高,拟真度就越高,单位面积的像素数量就越多,所以细节就越丰富。
密度类型 | 分辨率(px) | 屏幕像素密度(dpi) | dp与px关系 |
mdpi | 240*320 | 120dpi~~~160dpi | 1dp=0.75px~1px |
hdpi | 320*480 | 160dpi~~~240dpi | 1dp=1px~1.5px |
xhdpi | 480*800 | 240dpi~~~320dpi | 1dp=1.5px~2px |
xxhdpi | 720*1280 | 320dpi~~~480dpi | 1dp=2px~3px |
xxxhdpi | 1080*1920 | 480dpi~~~640dpi | 1dp=3px~4px |
density的获取(DisplayMetrics类里面的成员变量)
方式一
DisplayMetrics metrics=new DisplayMetrics();
Display defaultDisplay = getWindowManager().getDefaultDisplay();
defaultDisplay.getMetrics(metrics);
方式二
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
方式三
DisplayMetrics displayMetrics1 = Resources.getSystem().getDisplayMetrics();
4、dp、dip(Device-Independent Pixel)
设备无关像素,因为它的大小不是一个物理值,而是由操作系统根据屏幕大小和密度动态渲染出来的。
二、屏幕适配问题的本质
1、布局适配
2、布局组件适配
3、图片适配
4、代码适配
三、布局适配
布局适配是要使用多套布局来达到适配。如手机和平板的适配就需要使用到布局适配。
1、尺寸限定符---Android3.2版本以前
res/layout_large/main.xml
在系统屏幕尺寸>7英寸时采用适配平板的双面板布局,反之采用适配手机的单面板布局
还有:layout_small;layout_normal;layout_xlarge等
2、最小宽度限定符----Android3.2版本以后
开发者首先在项目中根据主流屏幕的最小宽度(smallestWidth)生成一系列values-sw<N>dp文件夹(含有dimens.xml文件),当运行到设备上时,系统会根据当前设备屏幕的最小宽度去匹配对应的values-sw<N>dp文件夹,而对应的values-sw<N>dp文件夹中的dimens.xml文字中的值时根据最小宽度而制定的,能够适配,如果没有找到对应的values-sw<N>dp文件夹,则会去寻找与之最小宽度相近的values-sw<N>dp文件夹,只会找小于或等于当前设备最小宽度的文件夹。
最小宽度的值=设备宽高最小值/(dpi/160);
如设备屏幕信息是1920*1080,480dpi,所以最小宽度=1080/(480/160)=360dp
3、布局别名(可以用在layout,也可以用在dimens上,主要看type属性)
当需要兼容3.2版本以前的尺寸限定符和3.2版本以后的最小宽度限定符,那你得同时维护layout-sw600dp和layout-large文件夹下的xml布局,所以使用布局别名很容易解决这个问题。
- 在layout文件下创建main_onepanes,main_twopanes两个布局文件
- res/value-large/main.xml (Android 3.2版本以前)
<resources>
<item name="main" type="layout">@layout/main_onepanes</item>
</resources>
res/values-sw600dp/main.xml(Android 3.2版本之后的)
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>
3.使用
setContentView(R.layout.main);
4、屏幕方向限定符
value-sw600dp-land 最小宽度600dp横向 values-sw600dp-port最小宽度600dp纵向
用在layout下,layout-sw600dp/main.xml,对于最小宽度>=600dp的设备,系统会自动加载layout-sw600dp/main.xml双面板布局,否则系统就会选择layout/main.xml手机布局。
四、布局组件适配
1、使用Relativelayout、Linearlayout,Constraatlayout不要使用绝对布局
2、使用match_parent、warp_content、layout_weight
3、百分比适配方法(以某一分辨率为基准,生成所有分辨率对应像素列表文件)
如:我们将以320*40的分辨率为基准,将屏幕的宽度分成320份,取值为x1~x320,将屏幕的高度分成480份,取值为y1~y480,
生成的文件如下:lay_x.xml(宽)
lay_y.xml(高)
有了基准之后,我们可以补全其他的尺寸如:1920*1080 1080/320=3.375px 1920/480=4px
最后,把这些文件放到res文件下:
分辨率为480x320的资源文件应放在res/values-480x320文件夹中;同理分辨率1920x1080的资源文件放在res/values-1920x1080文件夹中,必须在默认的values里面也创建对应默认lay_x.xml和lay_y.xml文件。
使用方式:
<ViewStub
android:id="@+id/tv"
android:layout_width="@dimen/x160"
android:layout_height="@dimen/y160" />
缺点:
- 由于实际上还是使用px作为长度的度量单位,所以和google的要求使用dp作为度量单位会有所背离
- 必须尽可能多的包含所有分辨率,因为这个是使用这个方案的基础,如果有某个分辨率缺少,将无法完成该屏幕的适配
- 过多的分辨率像素描述xml文件会增加软件大小和维护难度。
4、头条适配方案
核心原理: 当前设备屏幕总宽度(单位像素)/设计图总宽度(单位为dp)=density
density的意思就是1dp占用当前设备多少像素。
路径:ttps://github.com/JessYanCoding/AndroidAutoSize
侵入式少,可以随时更换,还可以自定义。
五、图片适配
1、logo多套图
2、点9图片