谈谈安卓屏幕相关信息

px、dp、sp代表的含义?啥是屏幕密度?啥叫屏幕分辨率?这些概念在开发中也是经常会碰到的,只了解一点概念也能满足基本开发的需求,不过为了构建完善知识体系,这里有必要好好总结下~

1、像素的概念

像素(pixel 简称px),构成图像的最小单位。每个像素点上可以携带颜色数据。我们平时看到的手机屏幕、电脑屏幕等其他终端屏幕上的画面其实都是由一个个像素点组合而成的。

2、屏幕尺寸的概念

屏幕尺寸其实就是屏幕对角线的长度。单位是英寸(inch),1 inch ≈ 2.54 cm。

在这里插入图片描述

3、屏幕分辨率

屏幕分辨率是指屏幕显示的分辨率,也就是屏幕上能够显示的像素最大数,一般以 纵向像素个数x横向像素个数 形式表示。如屏幕分辨率1920×1080的意思是水平方向可显示素数为1920个,垂直方向可显示像素数1080个。屏幕尺寸一样的情况下,分辨率越高,显示效果就越精细和细腻。不同型号的终端机屏幕分辨率可能不同。

4、dp和dpi

dpi 表示每英寸的像素数。dot per inch的缩写,可以反映屏幕的清晰度。dpi与屏幕分辨率和屏幕尺寸有关。具体的计算公式可参考下图:

在这里插入图片描述

由于安卓中不同型号的手机很多,都使用像素时不同手机上适配可能存在很大问题,这时安卓引入了屏幕密度density 和密度无关像素dp 的概念以统一安卓中的尺寸。

dp也称dip安卓中宽高的虚拟单位,Density Independent Pixels的缩写,表示密度无关像素,这是个自适应的值。

既然有了dp这个自适应的单位那么就需要有一个基准,安卓以每英寸像素数为160为基准而定义了一个转化公式:

  • density = dpi/160。 也即每英寸像素160的手机上 density = 1
  • px = dp*(dpi/160) 简化为 px = dp * density

这样dp 与px之间就存在了联系,而且dp是个相对概念,相同像素值在不同分辨率尺寸的手机上会动态适应。

如下为常见的屏幕分辨率对应的资源文件夹、density值:
在这里插入图片描述

5、sp

scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小常用的单位。

6、手机尺寸

(1)尺寸信息获取

        //方式1:获得像素(px)  
        WindowManager wi = getWindowManager();
        Display display = wi.getDefaultDisplay();
        Log.i("23333","高宽 (px)"+display.getHeight()+"   "+display.getWidth());
        
       // 方式2:像素获得方式(px)   
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        Log.i("23333",""+displayMetrics.widthPixels);
        Log.i("23333",""+displayMetrics.heightPixels);
        
        //方式3:获得像素(px) 
        DisplayMetrics  dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        Log.i("23333",""+  dm.widthPixels);
        Log.i("23333",""+ dm.heightPixels);

(2)屏幕密度获取

  float scale = getResources().getDisplayMetrics().density;

这个得到的不应该叫做屏幕密度,应该是密度的一个比例。不是真实的屏幕密度,而是相对于某个值的屏幕密度。 也可以说是相对密度。安卓中以每英寸像素数160为基准定义了density。 由于dpi与屏幕分辨率、屏幕尺寸有关 所以density是个动态值。

安卓api对这个值进行了封装可以通过api直接读取。

(2)验证下屏幕密度的计算

还是上图红米手机栗子(2040*1080 6.67英寸),接下来验证下density的计算:


        val pxSum = sqrt((2400 * 2400 + 1080 * 1080).toDouble()) // 屏幕尺寸上的像素数

        val dpi = pxSum/6.67 // 每英寸像素数

        Log.i(TAG, "计算出的density:${dpi / 160}") // 以160 为基准得出计算的density

        val scale = resources.displayMetrics.density
        Log.i(TAG, "通过api获取当前手机density:${scale}")
log:
I/MainActivity: 计算出的density:2.4660845801493227
I/MainActivity: 通过api获取当前手机density:2.75

可见计算出的还是有些差距的,我感觉应该是小数保留的问题,这个未具体看系统如何读取计算的流程。不过试了下上述的6.67小数舍去的结果就十分接近了~

7、尺寸转换工具

1、上文我们了解不同分辨率的手机上屏幕密度是不同的,google以 分辨率为320*480(像素密度为160)为基准定制了dp和px的关系即这种条件下 1dp = 1px,不同分辨率的我们按照倍数关系乘除计算即可。
2、上文我们又了解到安卓提供了相对密度(density)这样同分辨率的手机都会有相对值。
3、上文我们计算像素时:px = dp * (dpi / 160)还需知道手机的像素密度dpi太麻烦了,由于google封装了api提供了缩放比,方便我们快速的知道 dpi / 160 的值(dpi / 160 = density) 于是px = dp * density
于是封装各种转换工具:

/**
 * Created by sunnyDay on 2019/8/9 11:49
 * 尺寸转换工具
 * 公式:px = dp*density
 */
public class DensityUtils {
  /**
     * dp转px(使用公式)
     * 小数为了四舍五入
     */
    public static int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * px转dp(使用公式)
     */
    public static float px2dp(Context context, float pxVal) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (pxVal / scale);
    }

    /**
     * sp转px(使用系统推荐的工具)
     */
    public static int sp2px(Context context, float spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                spVal, context.getResources().getDisplayMetrics());
    }

    /**
     * px转sp(使用系统推荐的工具)
     */
    public static float px2sp(Context context, float pxVal) {
        return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
    }
}

以上dp转px,px转dp我们使用了公式计算的。其实使用系统的TypeValue也可以得到

end

参考:
Android屏幕尺寸详解

android 图片占用内存大小及加载解析

Android单位转换 (px、dp、sp之间的转换工具类

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值