Android 屏幕适配系列之基本知识

一、Android 屏幕的基本参数

1、屏幕信息参数

  • 屏幕尺寸(in):
    屏幕对角线的长度,单位英寸(in),一英寸 = 2.54 厘米。
  • 像素(px):
    pixel 屏幕上的点,常说的分辨率 1920 * 1080。
  • dpi:
    (Dots Per Lnch)每英寸的点数,即每英寸包含该的像素个数。
  • 屏幕密度、像素密度(density):
    density = dpi / 160 --> 把每英寸的像素点平分成 160 份
  • 设备独立密度(dp 或者 dip):
    Device independent pixels,Android 独有的单位,计算规则:
// 计算公式 dp = (dpi / 160)/ px
if (dpi == 160){
    dp == px ;
}else{
    dp = density / px;
    dp = (dpi /160) / px;
}
  • sp (类似于 dp) Scale-independent Pixels ,一般用于设置字体大小 ? 可缩放的设备独立密度。

二、DisplayMetrics 这个类的讲解

1. 该类的作用:

A structure describing general information about a display,
such as its size, density, and font scaling.

从这里我们可以看到 这是一个描述屏幕的基本的信息的结构体,我们可以理解为 JavaBean,它主要包括下面几个信息:

2. 获取方法:

// 法一
DisplayMetrics metrics = new DisplayMetrics();
Display display = activity.getWindowManager().getDefaultDisplay();
display.getMetrics(metrics); 
//法二
DisplayMetrics metrics=activity.getResources().getDisplayMetrics();
//法三
Resources.getSystem().getDisplayMetrics();

三、是否能够回答的问题?

1. getMetrics() 和 getRealMetric()的区别?

getMetrics():

public void get(Activity ac){
    DisplayMetrics displatMetrics = new DisplayMetrics();
    Display displsy = ac.getWindowManager().getDefaultDisplay();
    displsy.getMetrics(displatMetrics);
    Log.d(TAG, "density: "+ displatMetrics.density);
    Log.d(TAG, "densityDPI: "+ displatMetrics.densityDpi);
    Log.d(TAG, "scaledDensity: "+ displatMetrics.scaledDensity);
    Log.d(TAG, "heightPixels   "+ displatMetrics.heightPixels);
    Log.d(TAG, "widthPixels: "+ displatMetrics.widthPixels);
    Log.d(TAG, "xdpi: "+ displatMetrics.xdpi);
    Log.d(TAG, "ydpi: "+ displatMetrics.ydpi);
}

结果:

    density: 3.0
    densityDPI: 480
    scaledDensity: 3.0
    heightPixels   1776
    widthPixels: 1080
    xdpi: 480.0
    ydpi: 480.0

getRealMetrics():

DisplayMetrics displatMetrics = new DisplayMetrics();
ac.getWindowManager().getDefaultDisplay().getRealMetrics(displatMetrics);
Log.d(TAG, "density: "+ displatMetrics.density);
Log.d(TAG, "densityDPI: "+ displatMetrics.densityDpi);
Log.d(TAG, "scaledDensity: "+ displatMetrics.scaledDensity);
Log.d(TAG, "heightPixels   "+ displatMetrics.heightPixels);
Log.d(TAG, "widthPixels: "+ displatMetrics.widthPixels);
Log.d(TAG, "xdpi: "+ displatMetrics.xdpi);
Log.d(TAG, "ydpi: "+ displatMetrics.ydpi);

结果:

    density: 3.0
    densityDPI: 480
    scaledDensity: 3.0
    heightPixels   1920
    widthPixels: 1080
    xdpi: 480.0
    ydpi: 480.0

结论 :

getRealMetrics(displatMetrics)  获取到的是整个屏幕真实的信息;
getMetrics()获取的是屏幕信息中则不测量底部虚拟按键栏的高度;

2. sp 和 dp 的区别:

	Scale-independent Pixels(sp) – This is like the dp unit, but it is also scaled by the user’s font size preference. It is recommend
    you use this unit when specifying font sizes, so they will be adjusted for both the screen density and the user’s preference。
    sp 可以根据用户的字体偏好来缩放,举例:设置 14 sp 的字体,但是楷体和 宋体的大小是有区别的,如果设置成 14 dp ,则楷体和宋体是没有区别的。

3. 为什么 Android 推荐使用dp ,而不使用 px?

不使用px的原因:
	是由于不同的手机分辨率是不同的,相同的像素对应的尺寸也是不同的。
推荐使用dp的原因:
	是我们可以通过dp设置指定的尺寸,这个不受像素的影响,是像素无关的。从上面可以看出dp就是等于屏幕密度,从而可以得到1dp对应设备的像素,这样我们就可以设置真实的尺寸大小,这个大小跟像素是无关的。就是说dp能够让同一数值在不同的分辨率展示出大致相同的尺寸大小。

前提:
	在 1920 * 1080 和 960 * 540 的,屏幕尺寸一致的情况下 8英寸( 竖直方向)。
px 会出现的问题:
    	540  * 540 的 ImageView 控件占分辨率为 1920 * 1080  的 1/4 ,占 960 * 540 的1/2,,因为 1920 * 1080 或者 960 * 540 都铺满了整个屏幕,所以 ImageView 分别 占 用屏幕的 1/4 和 1/2。
解决原理(dp的由来):
	一个与 px 有对应关系的变量让 View 在不同分辨率上的像素占比达到一致性:
dp 解决这个问题:
	dp = (dpi / 160) * px, dpi 为 每英寸像素点,假设 1920 像素 对应 竖直方向 8 英寸的屏幕,960对应竖直方向 8 英寸 的屏:
计算相应的dpi:
    1920 *1080 的 dpi = 1920 / 8 = 240 px/in(240 个像素点每英寸) ,
    960 * 540    的 dpi = 960 / 8 = 120 px/in (160 个像素点每英寸)
计算屏幕密度(density):
    1920 * 1080 的 density:density = dpi /160 = 240 /160 = 1.5
    960 * 540 的 density:      density = dpi / 160 = 120 /240 = 0.75
假设 现在设置 Imageview 的宽为100dp:
	1920 * 1080 的屏幕上我们的真实像素为 px = 100 * 240 / 160 = 150 px,全屏像素占比为 150 / 1920 = 0.078125
    960 * 540 的屏幕上 我们真实的像素为 px =  100 * 120 / 160 = 75 px , 全屏像素占比为  75 / 960 = 0.078125

总结:

同一尺寸下,dp 让屏幕像素等分,从而达到屏幕等分(前提同一尺寸)将不同大小的像素等分成 n  = (1920 / 1.5 = 1280)等分,每等分的实际像素为 density 也就是 屏幕密度。dp 实际解决了让同一屏幕下不同分辨的屏幕占比一致性问题(这个在智能机顶盒和智能电视上比较常见,他们支持切换分辨率)

4. dp 为啥不能解决屏幕适配问题(Android 屏幕碎片化)?

由于 Android 碎片化的:屏幕尺寸和分辨率都不同,适配的目的是让其在屏幕占比达到一致性,dp 解决了同一尺寸下,不同分辨率的情况,但是无法解决不同尺寸
,不同分辨率的情况。
前提:
		在 分辨率 为 1920 * 1080 下,有 8英寸的屏和6英寸的屏。
1、计算dpi :
             8 英寸 dpi_8 = 1920 / 8  = 240 (px/in)
             6 英寸 dpi_6 = 1920 / 6  = 320 (px/in)
2、计算 density(屏幕密度):
             density_8 = dpi_8 / 160 = 240 / 160 = 1.5
             density_6 = dpi_6 / 160 = 320 / 160 = 2
假设 ImageView 的宽 为 100dp:
            px_8 = 100 * 1.5 = 150 px
            px_6 = 100 * 2 = 200 px
3、计算像素屏幕占比:
                 persent_px_8 = 150 / 1920
                 persent_px_6 = 200 / 1920
                 像素占比不一样了。
4、屏幕占比:
              persent_screen_8 = (150 / 1920 * 8) / 8
              persent_screen_6 = (200 / 1920 * 6 ) / 6

总结:
屏幕占比和像素占比保持了同步,但是同一像素下不同的尺寸的设备像素占比不一致了,原因是尺寸影响了 dpi

最后希望大家多多交流!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值