android适配指南

android适配,是android中非常重要的内容,我们平时做适配时,一般会相对布局、wrap_content、线性比例、单位dp等来做,仅仅做这些其实仅仅算及格,并不能完美适配,比如某个按钮宽高,如果仅仅是写一个dp,那么多数手机可能匹配,但仍然会有部分机型是不能满足要求的,那么我们该如何来做呢?我们先了解一下屏幕适配的基础知识,然后再详情适配方案

基础知识

  • 像素
    • 含义:通常所说的像素,就是CCD/CMOS上光电感应元件的数量,一个感光元件经过感光,光电信号转换,A/D转换等步骤以后,在输出的照片上就形成一个点,我们如果把影像放大数倍,会发现这些连续色调其实是由许多色彩相近的小方点所组成,这些小方点就是构成影像的最小单位“像素”(Pixel)。简而言之,像素就是手机屏幕的最小构成单位。
    • 单位:px(pixel),1px = 1像素点
    • 一般情况下UI设计师的设计图会以px作为统一的计量单位
  • 分辨率
    • 含义:手机在横向、纵向上的像素点数总和
    • 一般描述成 宽*高,即横向像素点个数 * 纵向像素点个数(如1080 X 1920)
    • 单位:px(pixel),1px = 1像素点
  • 屏幕尺寸(in)
    • 含义:手机对角线的物理尺寸
    • 单位 英寸(inch),一英寸大约2.54cm
    • 常见的尺寸有4.7寸、5寸、5.5寸、6寸
  • 屏幕像素密度(dpi)
    • 含义:每英寸的像素点数
    • 例如每英寸内有160个像素点,则其像素密度为160dpi
    • 单位:dpi (dots per inch)
    • 计算公式:像素密度 = 像素 / 尺寸 (dpi = px / in)
    • 标准屏幕像素密度(mdi):每英寸长度上还有160个像素点(160dpi),即称为标准屏幕像素密度(mdpi)
  • 密度无关像素(dp)
    • 含义:density-independent pixel,叫dp或者dip,与终端的实际物理像素点无关
    • 单位:dp,可以保证在不同屏幕像素密度的设备上显示相同的效果,是安卓特有的长度单位
    • 屏幕宽度是320dp
    • dp与px的转换: px = dp * (dpi/160)
  • 独立比例像素(sp)
    • 含义:scale-independent pixel,叫sp或sip
    • 单位:sp,字体大小专用单位
    • Android开发时用此单位设置文字大小,可根据字体大小首选项进行缩放
    • 推荐使用12sp、14sp、18sp、22sp作为字体大小,不推荐使用奇数和小数,容易造成精度丢失,12sp以下字体太小
  • sp与dp的区别
    • dp只跟屏幕的像素密度有关
    • sp和dp很类似但唯一的区别是,Android系统允许用户自定义文字尺寸大小,文字尺寸设置为标准时,1sp=1dp,当文字尺寸设置为特大号时,1sp>1dp
  • 屏幕分辨率对应表
密度类型分辨率屏幕像素密度density换算
低密度(ldpi)240X3200-1200.751dp=0.75px
中密度(mdpi)320X480120-16011dp=1px
高密度(hdpi)480X800160-2401.51dp=1.5px
超高密度(xhdpi)720X1280240-32021dp=2px
超超高密度1080X1920320-48031dp=3px
  • 屏幕尺寸、分辨率、像素密度关系
    在这里插入图片描述

适配优化

dp单位优化
  • 根据实际的宽高重新计算density并应用,我们使用dp时有时候会不对的原因是各大厂商对宽高的定制没有完全满足google的规则,导致density不正确,而 px = dp*density,从而引起实际像素计算不正确,所以根据屏幕实际的宽高重新计算density并应用,代码如下
//三种获取DisplayMetrics的方式
final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
//第二种方式
//DisplayMetrics metrics = new DisplayMetrics();
//Display display = getWindowManager().getDefaultDisplay();
//display.getMetrics(metrics);
//第三种方式
// DisplayMetrics metrics2 = Resources.getSystem().getDisplayMetrics();

        if(sNoncompatDensity == 0){
            // 系统的Density
            sNoncompatDensity = appDisplayMetrics.density;
            // 系统的ScaledDensity
            sNoncompatScaleDensity = appDisplayMetrics.scaledDensity;
            // 监听在系统设置中切换字体
            application.registerComponentCallbacks(new ComponentCallbacks() {
                @Override
                public void onConfigurationChanged(@NonNull Configuration newConfig) {
                        if(newConfig != null && newConfig.fontScale > 0){
                            sNoncompatScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
                        }
                }

                @Override
                public void onLowMemory() {

                }
            });
        }
        final float targetDensity = appDisplayMetrics.widthPixels / 480;
        final float targetScaledDensity = targetDensity * (sNoncompatScaleDensity/sNoncompatDensity);
        final int targetDensityDpi = (int)(160 * targetDensity);

        appDisplayMetrics.density = targetDensity;
        appDisplayMetrics.scaledDensity = targetScaledDensity;
        appDisplayMetrics.densityDpi = targetDensityDpi;

        final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
        activityDisplayMetrics.density = targetDensity;
        activityDisplayMetrics.scaledDensity = targetScaledDensity;
        activityDisplayMetrics.densityDpi = targetDensityDpi;
  • 自动生成 x1、x2 与像素的对应关系,实际使用时单位使用 x1、x2即可,设计图按照320*480来设计,这时候1px就等于x1,即可完成所有屏幕的适配,代码github地址
    在这里插入图片描述
    在这里插入图片描述
布局组件的适配
  • 使用密度无关像素指定尺寸
  • 使用相对布局或线性布局,不要使用绝对布局
  • 使用wrap_content、match_parent、权重
  • 使用minWidth、minHeight、lines等属性
  • dimens使用
布局的适配
图片适配
  • 普通图片和图标
  • 自动拉伸位图:Nine-Patch的图片类型
  • 动画、自定义View、shape
  • logo图标
屏幕密度对应的图片大小(px)图片资源目录
120dip36*36mipmap-ldpi
160dip48*48mipmap或者mipmap-mdpi
240dip72*72mipmap-hdpi
320dip96*96mipmap-xhdpi
480dip114*114mipmap-xxhdpi
640dip192*192mipmap-xxxhdpi
  • ImageView的ScaleType适配

    android:scaleType=“center” 保持原图的大小,显示在ImageView的中心。当原图的size大于ImageView的size时,多出来的部分被截掉
    android:scaleType=“center_inside”以原图正常显示为目的,如果原图大小大于ImageView的size,就按照比例缩小原图的宽高,居中显示在ImageView中。如果原图size小于ImageView的size,则不做处理居中显示图片
    android:scaleType=center_crop 以原图填满ImageView为目的,如果原图size大于ImageView的size,则与center_inside一样,按比例缩小,居中显示在ImageView上。如果原图size小于ImageView的size,则按比例拉升原图的宽和高,填充ImageView居中显示
    android:scaleType=“matrix” 不改变原图的大小,从ImageView的左上角开始绘制,超出部分做剪切处理
    androd:scaleType=“fit_xy” 把图片按照指定的大小在ImageView中显示,拉伸显示图片,不保持原比

刘海屏适配
折叠屏适配
版本适配
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值