Android屏幕尺寸适配常见方案smallestWidth

前言

介于目前的Android设备存在有不同的屏幕尺寸,屏幕分辨率,像素密度,Android应用在开发的过程必须要考虑到屏幕尺寸适配的问题,以保证在不同尺寸的Android设备上都能够正常运行。

基本概念

在开始说明适配方案之前,我们首先需要对如下几个概念了若指掌:屏幕尺寸,屏幕分辨率,屏幕像素密度。

1。 屏幕尺寸

屏幕尺寸是指的设备对角线的物理尺寸,常用单位为英寸。

1英寸 = 2.54cm

2. 屏幕分辨率

屏幕分辨率指的是设备在横向、纵向上的像素总和,常用宽*高的方式来描述。

宽指的是在横向上的像素点数,高是在纵向上的像素点数。
如480*600,则表示在横向上有480个像素点,在纵向上有600个像素点。

3. 屏幕像素密度

屏幕像素密度指的是设备每英寸的像素点数,单位dpi。

屏幕尺寸以160个像素作为基准,假设设备的每英寸有160个像素,则设备密度为160dpi,为1倍图适配。

倍图对应关系:

密度类型 分辨率 dpi dp换算
低密度(ldpi) 240x320 120 1dp=0.75px
中密度(mdpi) 320x480 160 1dp=1px
高密度(hdpi) 480x800 240 1dp=1.5px
超高密度(xhdpi) 720x1280 320 1dp=2px
超超高密度(xxhdpi) 1080x1920 480 1dp= 3px

一、屏幕适配方案

Android常见的UI适配方案主要包括如下几种:

  1. 多layout适配
  2. 屏幕分辨率限定符适配
  3. smallestWidth限定符适配

1. 多layout适配

多layout适配主要是针对某个分辨率,新建一个layout文件夹,名称为:layout-1024*600,横屏layout-land-1024*600
这种方法多见于横屏的特殊适配,如果横屏的UI和竖屏的UI差距非常大的情况下,可以为横屏单独设置布局。

Android屏幕尺寸适配常见方案smallestWidth_第1张图片

2. 屏幕分辨率限定符适配

屏幕限定符适配,是针对不同屏幕的分辨率创建values-xxx的文件夹,在遇到对应的屏幕分辨率时就可以找到对应的values文件夹,查找文件夹下的dimens.xml文件,确定每个屏幕尺寸下显示控件的大小。如下图:

Android屏幕尺寸适配常见方案smallestWidth_第2张图片

然后对每个values对应的不同屏幕分辨率,生成各种分辨率下面的dimens.xml文件。

    720px

需要注意的是采用此种方法,在每个dimens.xml文件里定义的尺寸大小多为px(像素),然而我们在实际的Android开发过程中遇到的开发尺寸多为dp,因此在实际的开发中此种方法使用场景并不是很频繁。

3. smallestWidth限定符适配

smallestWidth限定符适配原理和屏幕分辨率限定符适配一样,都是通过创建多个values文件夹,系统根据限定符去寻找对应的dimens.xml文件,以确定不同设备上的大小展示,如下图:

Android屏幕尺寸适配常见方案smallestWidth_第3张图片

和屏幕分辨率限定符屏幕分辨率限定符适配是拿 px 值等比例缩放不同的是, smallestWidth 限定符适配是拿 dp 值来等比缩放。

需要注意的是,最小宽度的宽度是不区分方向的,也就是对于设备来说无论是宽度还是高度,哪一边更小就认为哪一边是“最小宽度”。

代码中的设置大小

如果要在代码中设置大小,可以使用如下工具类:

public class ScreenSizeUtil {

    /**
     * 计算当前的SP的值
     * @param context
     * @param spSize :R.dimen.sp_16
     * @return
     */
    public static int getSP(Context context,@DimenRes int spSize){

        float pxValue = context.getResources().getDimension(spSize);//获取对应资源文件下的sp值
        //将px值转换成sp值
        return px2sp(context, pxValue);
    }

    /**
     * 计算当前的DP的值
     * @param context
     * @param dpSize :R.dimen.dp_16
     * @return
     */
    public  static int getDP(Context context,@DimenRes int dpSize){
        float pxValue = context.getResources().getDimension(dpSize);//获取对应资源文件下的sp值
        //将px值转换成sp值
        return px2dip(context, pxValue);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        if (context == null) {
            return (int) dpValue;
        }
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        if (context == null) {
            return (int) pxValue;
        }
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * px转换为sp
     * @param context
     * @param pxValue
     * @return
     */
    public static int px2sp(Context context,float pxValue){
        if (context == null) {
            return (int) pxValue;
        }
        final float scale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / scale + 0.5f);
    }
}

二、smallestWidth限定符适配的优势

虽然和分辨率限定符适配原理相同,都需要设置多个dimens.xml文件,但是在实际的开发过程中,还是相对建议使用smallestWidth限定符适配,其具有如下优势:

1. Android设配屏幕尺寸较多

和IOS设备不一样的是,Android设备有着多种多样的屏幕分辨率,因此如果采用屏幕分辨率来适配的话,则需要非常多的values,如果你没有适配对应分辨率的设备,则很有可能导致适配变形。
而实际上绝大部分的设备的最小宽度都大于360dp,这样的话smallestWidth限定符适配就不需要进行大量适配,而只需要添加少量的dimens.xml文件即可。

2. 适配单位便捷

屏幕分辨率适配的单位是px(像素),而基于Android设备不同的像素密度,这个单位在实际的开发中是很少会用到的。
smallestWidth限定符适配中的dan’wi单位是dp,对于文本大小也支持采用sp适配,在开发过程中十分便捷。

3. 适配宽松

屏幕分辨率限定符适配需要设备分辨率与 values-xx 文件夹完全匹配才能达到适配,如果不能完全匹配,则适配有可能无效而导致UI大幅变形。

而 smallestWidth 限定符适配寻找 dimens.xml 文件的原理是从大往小找,例如设备的最小宽度为 360dp,就会先去找 values-360dp,发现没有则会向下找 values-320dp,如果还是没有才找默认的 values 下的 demens.xml 文件,所以即使没有完全匹配也能达到不错的适配效果。

三、smallestWidth限定符适使用

鉴于需要生成多个dimens.xml文件,手动添加的代价过于高昂,而且当前已经有插件可以自动生成,目前推荐使用插件:ScreenMatch

1. ScreenMatch插件安装到Android Studio

和其他插件的安装一样,Android Studio可以通过Plugin Marketplace中查找插件,如下(图中由于我已经安装成功):

Android屏幕尺寸适配常见方案smallestWidth_第4张图片

在MarketPlace中找到ScreenMatch点击安装即可。

有可能在访问插件库时,MarketPlace加载不出来,可能需要魔法上网;或者访问插件库地址下载插件安装到本地也可以:https://plugins.jetbrains.com/
Android屏幕尺寸适配常见方案smallestWidth_第5张图片

2. dimens文件添加

我们需要添加一分dimens.xml文件作为适配的基准,文件内容主要声明尺寸,可参考附录。

3. screenMatch生成values

在插件导入之后,可以在values文件夹右键,选择ScreenMatch选项,然后选择在你添加了dimens.xml文件的module下执行,即可生成多个values文件夹。

4, 更新配置

在使用了ScreenMatch时,在Module层级的目录下会有一个ScreenMatch配置文件——screenMatch.properties,在其中可以更新配置,如果要更新需要适配的尺寸,可以在如下的代码中进行变动:

base_dp=600
# Also need to match the phone screen of [match_dp].
# If you have another dp values.
# System default values is 320,360,384,400,432,446.5,480,540,592,600,640,662,720,768,800,820,960,1024,1280,1365

base_dp是你的基准尺寸,可以在System default values中添加你需要适配的尺寸,然后重新执行第三步重新生成values及对应的dimens.xml文件。

5. 布局xml文件中的使用

接下来就是在布局xml文件中去使用大小了,可以采用@dimen/dp_12类似的方式来获取大小。
举例来说,如果要设计一个大小为宽为100dp,高为80dp的按钮,文字大小为20sp,可以在布局中这么写:

    

这样的话,系统就会根据当前设备的宽度dp去对应的dimens.xml文件中查到对应的长度了。

6. 代码中设置大小

代码中的话则需要通过getDimension()方法获取对应资源文件下的大小,工具类如下:

public class ScreenSizeUtil {

    /**
     * 计算当前的SP的值
     * @param context
     * @param spSize :R.dimen.sp_16
     * @return
     */
    public static int getSP(Context context,@DimenRes int spSize){

        float pxValue = context.getResources().getDimension(spSize);//获取对应资源文件下的sp值
        //将px值转换成sp值
        return px2sp(context, pxValue);
    }

    /**
     * 计算当前的DP的值
     * @param context
     * @param dpSize :R.dimen.dp_16
     * @return
     */
    public  static int getDP(Context context,@DimenRes int dpSize){
        float pxValue = context.getResources().getDimension(dpSize);//获取对应资源文件下的sp值
        //将px值转换成sp值
        return px2dip(context, pxValue);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        if (context == null) {
            return (int) dpValue;
        }
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        if (context == null) {
            return (int) pxValue;
        }
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * px转换为sp
     * @param context
     * @param pxValue
     * @return
     */
    public static int px2sp(Context context,float pxValue){
        if (context == null) {
            return (int) pxValue;
        }
        final float scale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / scale + 0.5f);
    }
}

总结

本文简述了smallestWidth这一常见的UI适配方法,相对于屏幕尺寸适配和多layout适配来说更加常见。

附录

dimens.xml文件




    
    @dimen/dp_15

    
    
    -60dp
    -30dp
    -20dp
    -12dp
    -10dp
    -8dp
    -5dp
    -2dp
    -1dp
    0dp
    0.1dp
    0.5dp
    1dp
    1.5dp
    2dp
    2.5dp
    3dp
    3.5dp
    4dp
    4.5dp
    5dp
    6dp
    7dp
    8dp
    9dp
    10dp
    11dp
    12dp
    13dp
    14dp
    15dp
    16dp
    17dp
    18dp
    19dp
    20dp
    21dp
    22dp
    23dp
    24dp
    25dp
    26dp
    27dp
    28dp
    29dp
    30dp
    31dp
    32dp
    33dp
    34dp
    35dp
    36dp
    37dp
    38dp
    39dp
    40dp
    41dp
    42dp
    43dp
    44dp
    45dp
    46dp
    47dp
    48dp
    49dp
    50dp
    51dp
    52dp
    53dp
    54dp
    55dp
    56dp
    57dp
    58dp
    59dp
    60dp
    61dp
    62dp
    63dp
    64dp
    65dp
    66dp
    67dp
    68dp
    69dp
    70dp
    71dp
    72dp
    73dp
    74dp
    75dp
    76dp
    77dp
    78dp
    79dp
    80dp
    81dp
    82dp
    83dp
    84dp
    85dp
    86dp
    87dp
    88dp
    89dp
    90dp
    91dp
    92dp
    93dp
    94dp
    95dp
    96dp
    97dp
    98dp
    99dp
    100dp
    101dp
    102dp
    103dp
    104dp
    105dp
    106dp
    107dp
    108dp
    109dp
    110dp
    111dp
    112dp
    113dp
    114dp
    115dp
    116dp
    117dp
    118dp
    119dp
    120dp
    121dp
    122dp
    123dp
    124dp
    125dp
    126dp
    127dp
    128dp
    129dp
    130dp
    131dp
    132dp
    133dp
    134dp
    135dp
    136dp
    137dp
    138dp
    139dp
    140dp
    141dp
    142dp
    143dp
    144dp
    145dp
    146dp
    147dp
    148dp
    149dp
    150dp
    151dp
    152dp
    153dp
    154dp
    155dp
    156dp
    157dp
    158dp
    159dp
    160dp
    161dp
    162dp
    163dp
    164dp
    165dp
    166dp
    167dp
    168dp
    169dp
    170dp
    171dp
    172dp
    173dp
    174dp
    175dp
    176dp
    177dp
    178dp
    179dp
    180dp
    181dp
    182dp
    183dp
    184dp
    185dp
    186dp
    187dp
    188dp
    189dp
    190dp
    191dp
    192dp
    193dp
    194dp
    195dp
    196dp
    197dp
    198dp
    199dp
    200dp
    201dp
    202dp
    203dp
    204dp
    205dp
    206dp
    207dp
    208dp
    209dp
    210dp
    211dp
    212dp
    213dp
    214dp
    215dp
    216dp
    217dp
    218dp
    219dp
    220dp
    221dp
    222dp
    223dp
    224dp
    225dp
    226dp
    227dp
    228dp
    229dp
    230dp
    231dp
    232dp
    233dp
    234dp
    235dp
    236dp
    237dp
    238dp
    239dp
    240dp
    241dp
    242dp
    243dp
    244dp
    245dp
    246dp
    247dp
    248dp
    249dp
    250dp
    251dp
    252dp
    253dp
    254dp
    255dp
    256dp
    257dp
    258dp
    259dp
    260dp
    261dp
    262dp
    263dp
    264dp
    265dp
    266dp
    267dp
    268dp
    269dp
    270dp
    271dp
    272dp
    273dp
    274dp
    275dp
    276dp
    277dp
    278dp
    279dp
    280dp
    281dp
    282dp
    283dp
    284dp
    285dp
    286dp
    287dp
    288dp
    289dp
    290dp
    291dp
    292dp
    293dp
    294dp
    295dp
    296dp
    297dp
    298dp
    299dp
    300dp
    301dp
    302dp
    303dp
    304dp
    305dp
    306dp
    307dp
    308dp
    309dp
    310dp
    311dp
    312dp
    313dp
    314dp
    315dp
    316dp
    317dp
    318dp
    319dp
    320dp
    321dp
    322dp
    323dp
    324dp
    325dp
    326dp
    327dp
    328dp
    329dp
    330dp
    331dp
    332dp
    333dp
    334dp
    335dp
    336dp
    337dp
    338dp
    339dp
    340dp
    341dp
    342dp
    343dp
    344dp
    345dp
    346dp
    347dp
    348dp
    349dp
    350dp
    351dp
    352dp
    353dp
    354dp
    355dp
    356dp
    357dp
    358dp
    359dp
    360dp
    365dp
    370dp
    400dp
    410dp
    422dp
    472dp
    500dp
    600dp
    640dp
    720dp

    376dp
    383dp
    412dp
    420dp
    441dp
    460dp
    552dp
    554dp
    622dp

    
    6sp
    7sp
    8sp
    9sp
    10sp
    11sp
    12sp
    13sp
    14sp
    15sp
    16sp
    17sp
    18sp
    19sp
    20sp
    21sp
    22sp
    23sp
    24sp
    25sp
    27sp
    28sp
    30sp
    31sp
    32sp
    34sp
    36sp
    38sp
    40sp
    42sp
    44sp
    48sp
    56sp
    64sp
    70sp
    72sp


```![多layout.jpg](https://img-blog.csdnimg.cn/img_convert/685686ef374b0567b7ebeae112419655.png)

你可能感兴趣的:(Android基础知识,android,android,studio)