Android屏幕适配

来源:互联网 发布:淘宝怎么赚集分宝 编辑:程序博客网 时间:2024/06/09 23:33

前言

Android屏幕碎片化严重,适配ui是一件让人头疼的问题。完成屏幕适配,深入了解Android UI资源加载机制是有必要的。

本文参考了:
- Android开发者文档-Supporting Different Screens
- Android开发者文档-Supporting Multiple Screens
- 郭霖-Android官方提供的支持不同屏幕大小的全部方法

有问题或者不好的地方欢迎评论互相探讨,你的评论是我的最大动力

需了解的概念

  • 屏幕尺寸

指屏幕对角线的物理尺寸(inch),1英寸=2.54cm

  • 屏幕分辨率

指屏幕横纵向像素点(px),例:1920x1080、2560x1440

  • 屏幕像素密度

每英寸的像素点(dpi)

  • 屏幕无关像素

指与屏幕像素点无关的表示单位(dp/dip),主要用于限定控件大小

密度类型 分辨率 像素密度 像素密度范围 换算(dp->px) ldpi 320x240 120 0~120 1dp -> 0.75px mdpi 480x320 160 120~160 1dp -> 1px hpdi 800x480 240 160~240 1dp -> 1.5px xhdpi 1280x720 320 240~320 1dp -> 2px xxhdpi 1920x1080 480 320~480 1dp -> 3px xxxhdpi 2560x1440 640 480~640 1dp -> 4px
  • 独立比例像素

指文字的统一度量单位(sp),主要用于限定字体大小,会根据用户的字体大小首选项进行缩放

  • 比较dp-sp
<!--分析applyDimension-->TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 22, getResources().getDisplayMetrics())public static float applyDimension(int unit, float value, DisplayMetrics metrics){    switch (unit) {        case COMPLEX_UNIT_PX:            return value;        case COMPLEX_UNIT_DIP:            return value * metrics.density;        case COMPLEX_UNIT_SP:            return value * metrics.scaledDensity;        case COMPLEX_UNIT_PT:            return value * metrics.xdpi * (1.0f/72);        case COMPLEX_UNIT_IN:            return value * metrics.xdpi;        case COMPLEX_UNIT_MM:            return value * metrics.xdpi * (1.0f/25.4f);    }    return 0;}dp->px公式:value * metrics.densitysp->px公式:value * metrics.scaledDensity

调整首选项中字体大小,density不会变化,scaledDensity跟随字号变化。因此有特殊需求的情况,不让应用字体跟随设置中字号变化,可直接调整scaledDensity的值。

public class MyApplication extends Application {    @Override    public void onCreate() {        super.onCreate();        Resources.getSystem().getDisplayMetrics().scaledDensity = Resources.getSystem().getDisplayMetrics().density;        getResources().getDisplayMetrics().scaledDensity = getResources().getDisplayMetrics().density;    }    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);        Resources.getSystem().getDisplayMetrics().scaledDensity = Resources.getSystem().getDisplayMetrics().density;        getResources().getDisplayMetrics().scaledDensity = getResources().getDisplayMetrics().density;    }}
  • Android资源加载流程

假设手机分辨率为1920x1080,屏幕密度为480dpi
1. 系统首先会寻找是否有480dpi(即xxhdpi)的目录,是否存在对应图片
2. 如果找到就使用该目录下的图片,如果没有就一直往更高屏幕密度的目录寻找
3. 如果更高的屏幕密度目录下存在该图片,则直接使用,如果不存在则寻找低屏幕密度的目录,直至找到

使用RelativeLayout(这个就不详细解释了)

较其他的布局,更能精确的调整view位置

使用wrap_content和match_parent(这个就不详细解释了)

确保你的布局能够自适应各种不同屏幕大小

使用.9图片

避免图片拉伸、变形

限定符

从上到下,优先级依次递减

配置 限定符 MCC MNC mcc310 语言 en-rUS 布局方向 ldrtl ldltr 最小宽度限定符 sw320dp 可获得宽度 w720dp 可获得高度 h720dp 屏幕尺寸 large 屏幕方面 long notlong 屏幕方向 port land UI模式 car appliance watch 夜晚模式 night notnight 屏幕像素密度 mdpi nodpi 触摸屏幕类型 notouch finger

* 例如values-xxhdpi-1080x1800要和values-xxhdpi配合使用,当在xxhdpi没匹配到对应分辨率的数据时,将会在xxhdpi中去匹配,不会匹配错分辨率

百分比布局

  1. 代码生成某一分辨率下的dp对应px值
  2. 使用分辨率限定符,创建不同分辨率下的dp数值文件

    • 注意:最好加上屏幕密度限定符一起限制会更加精准(values-xxhdpi-1080x1800)。在分辨率1080x1800下,可能适配不到values-1800x1080目录,使用以下代码检查对应分辨率及密度。
DisplayMetrics displayMetrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);int widthPixels = displayMetrics.widthPixels;   // 真实宽度分辨率int heightPixels = displayMetrics.heighthPixels;   // 真实高度分辨率int densityDPI = displayMetrics.densityDpi; // 屏幕密度
原创粉丝点击