一种非常好用的android屏幕适配,Android屏幕适配

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:

1.0px

...

320.0px

1.0px

...

480.0px

适配1080*1920分辨率:

xScale=1080/320=3.375;

yScale=1920/480=4;

新建res/values-1920x1080目录,新建dimens.xml:

3.375px //xScale*x1

...

1080.0px //xScale*x320

4.0px //xScale*y1

...

1920.0px//xScale*y480

在布局中使用:

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:

1dp

...

320dp

适配屏幕宽度为360dp设备:

scale=360/320=1.125;

新建res/values-sw360dp目录,新建dimens.xml:

1.125dp //scale*1

...

360dp //scale*360

在布局中使用:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值