`

Android学习笔记(1)—— Android屏幕和尺寸单位

 
阅读更多

网上很多解说挺混的,备忘一下。

 

获取屏幕参数代码:

DisplayMetrics metric = new DisplayMetrics();
//API 17之后使用,获取的像素宽高包含虚拟键所占空间,在API 17之前通过反射获取
context.getWindowManager().getDefaultDisplay().getRealMetrics(metric);
//获取的像素宽高不包含虚拟键所占空间
//context.getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels;  // 宽度(像素)
int height = metric.heightPixels;  // 高度(像素)
float density = metric.density;  // dp缩放因子
int densityDpi = metric.densityDpi;  // 广义密度
float xdpi = metric.xdpi;//x轴方向的真实密度
float ydpi = metric.ydpi;//y轴方向的真实密度

 

getRealMetrics()和getMetrics()获取到的屏幕信息差别只在于widthPixels或heightPixels的值是否去除虚拟键所占用的像素,和是否全屏和沉浸模式无关。

 

屏幕高度值包含了状态栏的像素,非沉浸模式下真实的Activity高度需要减去状态栏的高度。获取状态栏高度代码:

private int getStatusBarHeight() {
    Rect rect = new Rect();
    getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
    return rect.top;
}

 

屏幕参数Width和Height的值和屏幕方向有关,另外4个值和屏幕方向无关。

 

    术语解析1:

像素(Pixel:屏幕绘制的最小单位,无论在开发时使用什么尺寸单位,最终都需要转为像素。下简称px。

密度无关像素(Density independent pixel,简称dip/dp:简单来说是一个物理尺寸单位,宽高具有相同dp值的widget在不同屏幕上的物理尺寸是相同的(但实际上可能是近似,因为Android设备使用广义密度而不是真实密度,下面会讲述),和屏幕尺寸以及分辨率没有关系。下简称dp。

屏幕大小(Screen size):如果没特别说明,屏幕大小是指其对角线长度,单位为英寸。

屏幕密度(Dots per inch,简称Dpi):屏幕每英寸上有多少个px点。计算公式:sqrt(widthPixels *widthPixels + heightPixels * heightPixels) / screenSize

 

为什么Android要使用dp而不是传统的px作为widget长度单位:

        Android的主要交互是触控,而人的手指头大小变化范围比较小。如果以px作为长度单位,在一个大屏幕低分屏上可以正常触控的按钮,换到一个一个小屏幕高分屏上可能很难按到(因为物理尺寸变小了,手指头可不能跟着变小),所以需要使用一个和屏幕参数无关的单位,维持交互控件的物理尺寸。
 
    术语解析2:
广义密度(Generalized density):从上面屏幕密度的计算公式可知,通过更改分辨率或者屏幕尺寸可以搞出无数种真实屏幕密度,不同的屏幕密度意味着,绘制相同的物理尺寸的widget要使用的px数是不一样的。假定要让一张图片在10个屏幕密度不一样的设备上以相同物理尺寸显示(不使用动态缩放),那么开发者需要准备10张px面积不同的图片以获得最佳显示效果,显然这是不可接受的。对此Android的解决方案是牺牲widget在物理尺寸上的一致性,在不同密度的设备上widget物理尺寸只是近似而不是相同,换取适配工作量的降低。
具体的做法:将一定范围的屏幕密度的设备视为一个特定的密度,比如屏幕密度在240左右的设备视为高密度(hdpi),在320左右的视为超高密度(xhdpi)等。注意的是,在两个广义密度之间并没有明确的边界值,屏幕具体属于何种广义密度由系统决定而不是由真实密度决定,系统在进行绘制换算时也只会使用广义密度。下简称density。

dp缩放因子:每个dp对应多少个px。这个值在Android系统的变量命名也是density,但实际上和屏幕密度是两回事,所以我称之为scale factor。先说说这个值的来源,Android系统规定在广义密度为160(mdpi)的设备上1dp=1px,这是一个定值。对于密度为320(xhdpi)的设备,后者每英寸像素点为前者的320/160=2倍。在前者使用1个像素绘制的物体,在后者需要使用4个像素(2*2)绘制,对于用户来说它的物理大小才是相同的,那么显然,对于后者来讲1dp=2px。换句话说,dp缩放因子 = density / 160,同时可以推出公式px = dp * dp缩放因子 = dp * (density / 160) 。下简称factor。
 
    从上面延伸的公式:
屏幕的dp数:
widthDps = widthPixels * 160 / density = widthPixels / factor
heightDps = heightPixels * 160 / density = heightPixels / factor

维持widget在不同密度屏幕的比例:
所谓维持比例也就是说widget尺寸和屏幕尺寸的比值相同,有
WidgetWidthDpA / ScreenWidthDpA = WidgetWidthDpB / ScreenWidthDpB ,那么
WidgetWidthDpB = WidgetWidthDpA * ScreenWidthDpB / ScreenWidthDpA ,或
WidgetWidthDpB = WidgetWidthDpA * rate
其中rate = (screenWidthPixelsB / densityB) / (screenWidthPixelsA / densityA)
实际使用中,因为这个比值不仅和广义密度比有关并且和分辨率比有关,要完整适配所有设备比较困难,一般推荐使用空白区变长的方法完成适配而不是维持画面比例。
 
分享到:
评论

相关推荐

    Android学习笔记(十)——实现新闻列表

    Android学习笔记(一)——创建第一个Android项目 Android学习笔记(二)android studio基本控件及布局(实现图片查看器) Android学习笔记(三)android studio中CheckBox自定义样式(更换复选框左侧的勾选图像) ...

    Android Training学习笔记——Navigation 参考源码

    在Android应用开发中,Navigation组件是一个强大的工具,用于管理应用程序中的屏幕..."Android Training学习笔记——Navigation 参考源码"提供了一个深入学习和实践的平台,对于提升Android开发技能具有显著的价值。

    Android Training学习笔记——Navigation 参考源码(ListView版)

    总之,通过阅读和理解这篇“Android Training学习笔记——Navigation 参考源码(ListView版)”,开发者可以获得关于如何在Android应用中创建基于ListView的导航系统的宝贵经验。源码分析将加深对Navigation组件和...

    Android学习笔记之——Content Providers

    之前博文《 Android学习笔记之——Android Studio的安装(3.6版本)、Java的基本语法及Android的概述 》曾经介绍过android有四大组件。本博文学习一下Content Providers(内容提供器) 目录 Android运行时 ...

    Android Training学习笔记——RecyclerView和CardView

    这篇“Android Training学习笔记”主要围绕这两个组件展开,旨在帮助开发者提升他们的Android应用设计能力。 RecyclerView是Android SDK提供的一种列表视图控件,取代了早期的ListView。RecyclerView的优势在于它的...

    Android开发者学习笔记——View、Canvas、bitmap

    Android开发者学习笔记——View、Canvas、bitmap Android 开发者学习笔记——View、Canvas、bitmap 是 Android 开发中常用的类,本文将通过实例讲解 View、Canvas 等相关知识点。 从资源中获取位图 在 Android ...

    Android学习笔记——Http通信 源码

    这篇"Android学习笔记——Http通信 源码"主要探讨了如何在Android应用中利用WebView控件加载网页以及使用ImageView控件加载网络图片,这两部分是Android应用与互联网交互的常见场景。 首先,我们来深入理解一下`...

    Android学习笔记——获取网络图片并显示

    `android:layout_width`和`android:layout_height`决定图片显示的尺寸,`android:src`初始可以设置一个默认的图片资源。 接下来,我们将在Java代码中实现获取网络图片并显示的功能。Android提供了多种方法来实现这...

    Android学习笔记——Canvas & clipRect

    这篇学习笔记将深入探讨这两个概念及其在实际应用中的使用。 首先,Canvas可以理解为画布,它是Android系统提供的用于在屏幕上绘制图形的对象。在Android中,我们可以通过Canvas来绘制各种形状,如线条、矩形、圆、...

    Android 学习笔记——利用JNI技术在Android中调用、调试C++代码

    这篇“Android学习笔记——利用JNI技术在Android中调用、调试C++代码”将带你深入理解如何在Android应用中使用JNI来调用C++代码,以及如何进行调试。以下是对这一主题的详细阐述。 1. **JNI简介** JNI是Java平台的...

    Android Training学习笔记——App Bar 参考源码

    这篇文章是基于“Android Training”系列的学习笔记,主要探讨了App Bar的设计原理和参考源码分析。下面将详细阐述App Bar的相关知识点。 首先,App Bar是Android设计指南中推荐的用户界面元素,它位于屏幕顶部,...

    【安卓项目】——新闻资讯类项目

    Android学习笔记(一)——创建第一个Android项目 Android学习笔记(二)android studio基本控件及布局(实现图片查看器) Android学习笔记(三)android studio中CheckBox自定义样式(更换复选框左侧的勾选图像) ...

    Android开发笔记——UI基础编程

    这份"Android开发笔记——UI基础编程"的资料集包含了两部分:新版Android开发教程+笔记七--基础UI编程1.pdf和新版Android开发教程+笔记七--基础UI编程2.pdf,将深入讲解Android应用程序中用户界面的设计与实现。...

    Android 学习笔记——旋转模拟器方向,全屏,窗口生命周期

    这篇“Android学习笔记”主要探讨了如何在模拟器中旋转屏幕方向、实现应用全屏显示以及理解窗口生命周期。这些概念对于创建用户友好且性能优良的Android应用程序至关重要。 首先,让我们详细讨论如何在Android...

    Android学习笔记之——捕获WIFI列表,并按RSSI强度来排序

    之前博文《 Android学习笔记之——Content Providers》曾经介绍过将联系人的信息读入,然后显示。其实本博文就很像了hhh 在博文《Android学习笔记之——获取WIFI的RSSI以及名称》已经实现了获取wifi的名称以及其...

    Android学习笔记——Menu介绍(二)

    上下文菜单和上下文操作模式都是Android中增强用户体验的重要工具,它们可以根据应用的需求灵活地提供针对特定内容的操作选项。理解并熟练运用这些菜单类型,可以帮助开发者创建更加直观和功能丰富的用户界面。

    Android开发笔记——环境搭建

    这篇"Android开发笔记——环境搭建"涵盖了这一基础但至关重要的过程,旨在帮助初学者快速入门。以下将详细介绍Android开发环境的搭建步骤,以及ADB(Android Debug Bridge)的相关知识。 首先,我们需要安装Java ...

    Android Training学习笔记——Navigation 参考源码(NavigationView版)

    本篇文章将深入探讨`NavigationView`与`Navigation`组件的使用,结合Android Training的学习笔记,我们将理解其核心概念、功能以及如何在实践中应用。 `NavigationView`是Android Design Support Library的一部分,...

Global site tag (gtag.js) - Google Analytics