当前位置: 移动技术网 > 移动技术>移动开发>Android > Android屏幕适配

Android屏幕适配

2020年07月24日  | 移动技术网移动技术  | 我要评论

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)限定符

    参考Android 屏幕适配:最全面的解决方案

百分比适配方案:

通过宽高限定符:(废弃)

原理:
  1. 根据设计图宽高(例:480*320,单位px)将屏幕等分320份,在res目录下,新建 values-480x320 目录,在其中新建 dimens.xml 文件,在其中根据等分定义基准值;
  2. 根据适配分辨率(例:1920*1080,单位px),及步骤1计算出比例值(xScale,yScale),在res目录下,新建 values-1920x1080 目录,在其中新建 dimens.xml 文件,再根据比例值算出对应值;
  3. 使用时在控件属性填写设计图对应值;
  4. 适配其他分辨率重复步骤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"/>
参考:

Android 屏幕适配方案

封装库:

AndroidAutoLayout

缺陷:

需要精准匹配分辨率,产生额外文件夹.

通过最小宽度限定符:

原理:

来源于方案通过宽高限定符,与其原理类似,弥补了其需要精准匹配的缺陷,因为系统会根据最小宽度限定符去选择最接近的values目录.

  1. 根据设计图宽(例:320,单位dp/px)将屏幕等分320份,在res目录下,新建 values-sw320dp 目录,在其中新建 dimens.xml 文件,在其中根据等分定义基准值;
  2. 根据适配屏幕宽度(例:360dp),及步骤1计算出比例值(scale),在res目录下,新建 values-sw360dp 目录,在其中新建 dimens.xml 文件,再根据比例值算出对应值;
  3. 使用时在控件属性填写设计图对应值;
  4. 适配其他分辨率重复步骤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"/>
参考:

Android 目前最稳定和高效的UI适配方案

自动化工具:

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

缺陷:

产生额外文件夹.

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;
说明:
  1. 要在activity的setContentView()之前调用;
  2. 获取状态栏和导航栏高度异常:
    • 获取高度使用的是Application#getResources,而其中用于计算的density已经被我们修改;
    • 这时候使用Resources.getSystem()来获取系统的Resources,然后获取高度.
参考:

一种极低成本的Android屏幕适配方式

封装库:

AndroidAutoSize

本文地址:https://blog.csdn.net/tangzeyu7/article/details/107509990

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网