Android屏幕适配
程序员文章站
2022-03-21 17:31:43
Android屏幕适配author:TzyAndroid屏幕适配基础知识:官方dp适配存在的问题:适配方案:传统方案:(以下结合使用)百分比适配方案:通过宽高限定符:(废弃)原理:例子:参考:封装库:缺陷:通过最小宽度限定符:原理:例子:参考:自动化工具:缺陷:density适配方案:(推荐)原理:例子:说明:参考:封装库:基础知识:dp=设备独立像素=dippx=desity*dpdensity=dp...
Android屏幕适配
author:Tzy
基础知识:
dp=设备独立像素=dip
px=desity*dp
density=dpi/160
dpi=屏幕对角线像素/屏幕尺寸
官方dp适配存在的问题:
以现在市面上最常见的设备类型为例,分辨率1080*1920,尺寸5.5,计算出来:
density≈2.5
设备实际宽度(单位dp)为:
1080/2.5≈430dp
假设设计图宽度为360dp,那屏幕就比设计图要宽,如果设备屏幕宽度小于360dp,还会出现显示不全的情况,无法做到不同设备显示效果一致.
适配方案:
传统方案:(以下结合使用)
-
dp/sp
-
自适应布局:
- ViewGroup: 使用LinearLayout,RelativeLayout
- View: 使用match_parent,wrap_content,weight
- 图片: .9图,多分辨率图片资源
-
最小宽度(Smallest-width)限定符
百分比适配方案:
通过宽高限定符:(废弃)
原理:
- 根据设计图宽高(例:480*320,单位px)将屏幕等分320份,在res目录下,新建 values-480x320 目录,在其中新建 dimens.xml 文件,在其中根据等分定义基准值;
- 根据适配分辨率(例:1920*1080,单位px),及步骤1计算出比例值(xScale,yScale),在res目录下,新建 values-1920x1080 目录,在其中新建 dimens.xml 文件,再根据比例值算出对应值;
- 使用时在控件属性填写设计图对应值;
- 适配其他分辨率重复步骤2.
例子:
设计图为480*320分辨率,新建res/values-480x320目录,新建dimens.xml:
<resources>
<dimen name="x1">1.0px</dimen>
...
<dimen name="x320">320.0px</dimen>
<dimen name="y1">1.0px</dimen>
...
<dimen name="y480">480.0px</dimen>
</resources>
适配1080*1920分辨率:
xScale=1080/320=3.375;
yScale=1920/480=4;
新建res/values-1920x1080目录,新建dimens.xml:
<resources>
<dimen name="x1">3.375px</dimen> //xScale*x1
...
<dimen name="x320">1080.0px</dimen> //xScale*x320
<dimen name="y1">4.0px</dimen> //xScale*y1
...
<dimen name="y480">1920.0px</dimen> //xScale*y480
</resources>
在布局中使用:
<TextView
android:layout_width="@dimen/x100"
android:layout_height="@dimen/y30"/>
参考:
封装库:
缺陷:
需要精准匹配分辨率,产生额外文件夹.
通过最小宽度限定符:
原理:
来源于方案通过宽高限定符,与其原理类似,弥补了其需要精准匹配的缺陷,因为系统会根据最小宽度限定符去选择最接近的values目录.
- 根据设计图宽(例:320,单位dp/px)将屏幕等分320份,在res目录下,新建 values-sw320dp 目录,在其中新建 dimens.xml 文件,在其中根据等分定义基准值;
- 根据适配屏幕宽度(例:360dp),及步骤1计算出比例值(scale),在res目录下,新建 values-sw360dp 目录,在其中新建 dimens.xml 文件,再根据比例值算出对应值;
- 使用时在控件属性填写设计图对应值;
- 适配其他分辨率重复步骤2.
例子:
设计图为480*320分辨率,新建res/values-sw320dp,新建dimens.xml:
<resources>
<dimen name="s1">1dp</dimen>
...
<dimen name="s320">320dp</dimen>
</resources>
适配屏幕宽度为360dp设备:
scale=360/320=1.125;
新建res/values-sw360dp目录,新建dimens.xml:
<resources>
<dimen name="s1">1.125dp</dimen> //scale*1
...
<dimen name="s320">360dp</dimen> //scale*360
</resources>
在布局中使用:
<TextView
android:layout_width="@dimen/s100"
android:layout_height="@dimen/s30"/>
参考:
自动化工具:
缺陷:
产生额外文件夹.
density适配方案:(推荐)
原理:
根据设计图宽度(单位dp)自定义density.
density=设备宽度(单位px)/设计图宽度(单位dp)
例子:
设计图宽度为360dp:
sizeInPx=360;
final DisplayMetrics systemDm = Resources.getSystem().getDisplayMetrics();
final DisplayMetrics appDm = application.getResources().getDisplayMetrics();
final DisplayMetrics activityDm = activity.getResources().getDisplayMetrics();
activityDm.density = activityDm.widthPixels / (float) sizeInPx;
activityDm.scaledDensity = activityDm.density * (systemDm.scaledDensity / systemDm.density);
activityDm.densityDpi = (int) (160 * activityDm.density);
appDm.density = activityDm.density;
appDm.scaledDensity = activityDm.scaledDensity;
appDm.densityDpi = activityDm.densityDpi;
说明:
- 要在activity的setContentView()之前调用;
- 获取状态栏和导航栏高度异常:
- 获取高度使用的是Application#getResources,而其中用于计算的density已经被我们修改;
- 这时候使用Resources.getSystem()来获取系统的Resources,然后获取高度.
参考:
封装库:
本文地址:https://blog.csdn.net/tangzeyu7/article/details/107509990
上一篇: 开发 Laravel 扩展的基本流程