转载请注明出处:http://blog.csdn.net/my_truelove/article/details/66584865

訪问 ruicb.com,一键抵达我的博客!

扫描左側或右下方二维码。关注我的公众号,及时获取最新文章推送!



1 概念扫盲 inch、px 与 dpi

1.1 屏幕尺寸之 inch

不论是电视、平板,还是手机。所说的屏幕尺寸是指 屏幕对角线的长度,单位是英寸(inch),1 英寸相当于 2.54 厘米;

即:1 inch ≈ 2.54 cm

1.2 屏幕分辨率之 px

屏幕分辨率指 设备屏幕上的像素个数。每个像素点的边长为 1px,其是组成手机屏幕的最小单位。

常说的手机分辨率为 1920*1080。即手机横向有 1080 个像素点。竖向有 1920 个像素点。

屏幕尺寸一样的情况下,分辨率越高,显示效果就越精细和细腻。

注:在 Android 开发中。涉及与 View 尺寸(宽高)、位置(坐标)相关的数据,终于都是以 px 为单位进行度量和绘制的。

1.3 像素密度之 dpi

像素密度。单位是 dpi,即 dot-per-inch,顾名思义,表示 每英寸上的像素点数

像素密度 与之前提及的 屏幕尺寸屏幕分辨率 息息相关,确保理解了前面的内容再继续向下学习。

举个栗子

以 Google 亲儿子 Nexus 5 为例,其屏幕尺寸为 4.95 inch,分辨率为 1920 * 1080,则其像素密度为:

√(1920² + 1080²) / 4.95 (√ 代表开根号)

凝视:分辨率为 1920 * 1080,表示纵向、横向分别由 1920 和 1080 个像素点组成。那么屏幕对角线的像素点数就是√(1920² + 1080²);又屏幕尺寸(即对角线长度)为 4.95 inch。所以单位英尺上的像素点数即为:√(1920² + 1080²) / 4.95 = 445,也就是像素密度。

2 碎片化下的 dip 与 sp

在開始之前,先聊聊老生常谈的 Android 碎片化问题。

Android 的开源,让各大厂商趋之若鹜,各种定制硬件和 ROM,从而导致 Android 设备碎片化严重。

手机尺寸与分辨率就是硬件层碎片化的一个体现:相同大小的手机屏幕,分辨率可能不一样;异或分辨率一样的手机,屏幕尺寸又大小不一。

开发人员根本无法通过某一个因素(尺寸或分辨率)来适配 UI。所以写出来的布局无法在每个手机上都能非常好的 work。

看到这,你预计犯嘀咕了:这可咋办?别急。Google 为我们提供了 密度无关像素缩放无关像素 来应对不同分辨率的问题。继续看。

2.1 密度无关像素之 dip

密度无关像素。单位为 dip(简称 dp,下同),即 density-independent pixels ,顾名思义,该单位与手机的屏幕像素没有绝对关系。

注:注意区分此处的 dp 和前面说的 dpi。

所以,dp 才是开发中适配屏幕的最佳单位。在 xml 中写布局时,能够直接以 dp 为单位;在 Java 代码中则能够将 dp 转换为 px 以进行适配。

前面说过,在开发中所有与尺寸、宽高都是以 px 进行度量的,那么我们使用的 dp 与 px 之间究竟是怎样换算的呢?带着问题继续往下看。

在此提醒下,请确保对于前面的概念都理解了。为了更好的学习后面的知识,容我再啰嗦的回想下:

  • 尺寸之 inch:屏幕对角线的长度;
  • 分辨率之 px:纵、横方向上的像素点数;
  • 像素密度之 dpi:,每英寸上的像素点数。

复习完,我们继续往下看 px、dpi 与 dp 的相互关系。敲黑板划重点了啊:

dp 与 px 之间的换算,取决于当前设备的 dpi。

嗯,就这一句重点。别激动同学,放下你手中的鞋子,容我再举个栗子。

曾经面说的 Nexus 5 为例。其 dpi ≈ 445,此时 1dp = 3px。这里的 3 当然不是我蒙的,有对比表:

120dpi - 160dpi 1dp = 1px

160dpi - 240dpi 1dp = 1.5px

240dpi - 320dpi 1dp = 2px

320dpi - 480dpi 1dp = 3px

480dpi - 640dpi 1dp = 4px

同学,先别着急背换算倍数。dp 与 px 的换算倍数在开发中是能够通过 Api 获取的,我们后面会说。

2.2 缩放无关像素之 sp

缩放无关像素,即 scale-independent pixels(简称 sp),为减少理解难度。这么说:

sp 与 dp 能够理解为同种类型的度量单位,差别于 dp 用来度量 尺寸、宽高,sp 用来度量字体的大小。

dp 能够依据不同的屏幕密度相应的转换成不同的 px,以适配屏幕;sp 则其能够依据文字大小首选项进行缩放,达到适配不同屏幕的效果。

从主要的 inch、px 与 dpi,聊到 Android 碎片化。再到碎片化的解决方式 dp 与 sp。基础知识都介绍到了,后面再融会贯通,说说怎样使用。

3 从 H, XH, XXH 说起

在开发中涉及图片资源时,为了适配屏幕。我们常常会在不同的 drawable 文件夹下各放置一套资源。这样在不同 dpi 的设备上,对程序进行编码时,会使用相应 drawable 文件夹下的资源。以下是对比表(顺便整合 dp 与 px 的换算):

dpi drawable dp / px
120dpi - 160dpi mdpi 1
160dpi - 240dpi hdpi 1.5
240dpi - 320dpi xhdpi 2
320dpi - 480dpi xxhdpi 3
480dpi - 640dpi xxxhdpi 4

4 layout weight 的使用方法

weight 表示权重,我们知道权重是一个相对的概念。那么在布局中有什么作用呢?

如果有这种需求:

- 横向上有两个按钮。各占屏幕宽度的一半,咋写?

- 或者是三个按钮,各占屏幕宽度三分之中的一个,咋写?

- 或者两个按钮,右側的自适应,左側的占剩下的区域呢?

最好还是动手写写,篇幅有限就不举栗子了。这种需求使用 weight 实现将十分的简单。注意看代码中控件的 android:layout_weight 属性,其决定了该控件的权重。

第一个:

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/colorPrimary"
android:text="Button 1" /> <Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/colorAccent"
android:text="Button 2" /> </LinearLayout>

效果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXlfVHJ1ZUxvdmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="平分" title="">

第二个和第一个相似,不再举例,看第三个:

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/colorPrimary"
android:text="Button 1" /> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="Button 2" /> </LinearLayout>

效果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXlfVHJ1ZUxvdmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="填充剩余 " title="">

看了上面的演示样例代码。你也许会非常疑惑,以下说说 Android 是怎样依据 weight 布局的。

事实上 weight 的使用方法非常easy。理解之后就是一句话,以上面讨论的宽度为例:

View 的实际宽度 = layout_height 设置的值 + 父布局剩余宽度 * layout_weight 所占权重

以第一个演示样例中,button 1 和 button 2 的宽度 layout_width = 0,权重 layout_weight = 1。如果屏幕宽度为 w。套公式。

则 button 1 的宽度 = 0 + (w - 0 - 0) * 1/(1 + 1) = w/2

当中:

  • w - 0 - 0 表示父布局剩余宽度。由于两个 button 宽度都为 0;
  • 1/(1 + 1) 表示 button 1 在剩余宽度中所占的权重。由于 button 1 的权重为 1,button 2 的权重为 1,所以总权重就是 1 + 1。

button 2 宽度的计算与 button 1 一样,结果相同为 w/2。能够看出。button 1 和 button 2 各占屏幕宽度 w 的一半。

以相同的方式理解第三个样例:

button 2 的宽度 layout_width = "wrap_content"。宽度未知,那如果为 w’,屏幕宽度仍为 w。

则 button 1 的宽度为:0 + (w - 0 - w’) * 1/(1 + 0) = w - w’

计算方式不再解释。最后的结果能够看出,不管 button 2 宽度怎么自适应,button 1 和 button 2 宽度都为 w。也就实现了 button 1 填充剩余区域的效果。

注:weight 仅仅在 LinearLayout 中起作用。限于篇幅非常多没有展开。很多其它使用技巧能够參考 Android Develop 站点 或其它博客,值得学习。

5 px 与 dp 的相互转换

前面介绍 sp、dpi 与 dp 的关系时,提到了在不同 dpi 下 dp 与 px 转换比例不同。

那么。开发中怎样获取这一比例呢?以下为大家提供了一个现成的辅助类,欢迎拿走使用,但记得略微看一下代码。

/**
* Android 中 dp 与 px 的转换
* <p/>
* Created by ruicbAndroid on 2017/3/26.
*/
public class DpAndPxHelper { private static float scale; private static float getScale(Context context) {
if (scale == 0) {
DisplayMetrics metrics =
context.getResources().getDisplayMetrics();
scale = metrics.density;
}
return scale;
} /**
* px to dp
*/
public static int px2dp(Context context, int px) {
//+0.5 向上取整
return (int) (px / getScale(context) + 0.5f);
} /**
* dp to px
*/
public static int dp2px(Context context, int dp) {
//+0.5 向上取整
return (int) (dp * getScale(context) + 0.5f);
}
}

以上就是本次分享的所有内容了。如果认为对你有帮助,点赞表示一下。

若有不论什么问题,欢迎留言交流。或关注我的公众号了解很多其它。

Android 屏幕适配扫盲、教程的更多相关文章

  1. (转)android屏幕适配

    声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息 原文作者: zhuangyujia 原文地址: http://my.eoe.cn/zhuangyujia/archiv ...

  2. Android屏幕适配全攻略 (转载)

    http://blog.csdn.net/jdsjlzx/article/details/45891551 https://github.com/hongyangAndroid/AndroidAuto ...

  3. 【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)

    来源:http://blog.csdn.net/zhaokaiqiang1992 更多:Android AutoLayout全新的适配方式, 堪称适配终结者 Android的屏幕适配一直以来都在折磨着 ...

  4. Android屏幕适配全攻略(最权威的官方适配指导)(转),共大家分享。

    Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因.重要概念.解决方案及最佳实践,我相信如果你能认真的学习 ...

  5. Android屏幕适配全攻略(最权威的官方适配指导) (转)

    招聘信息: Cocos2d-X 前端主程 [新浪微博]手机客户端iOS研发工程师 20k-40k iOS 开发工程师 iOS高级开发工程师(中国排名第一的企业级移动互联网云计算公司 和创科技 红圈营销 ...

  6. 腾讯优测| 让Android屏幕适配开发更简单-Google百分比布

    文/腾讯优测工程师 吴宇焕 腾讯优测优社区干货精选~ 相信开发同学都被安卓设备碎片化的问题折磨过,市面上安卓手机的主流屏幕尺寸种类繁多,给适配造成很大的困难.就算搞定了屏幕尺寸问题,各种分辨率又让人眼 ...

  7. Android 屏幕适配(一)百分比布局库(percent-support-lib) 解析与扩展

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46695347: 本文出自:[张鸿洋的博客] 一.概述 周末游戏打得过猛,于是周 ...

  8. Android重写getResources规避用户调整系统字体大小影响Android屏幕适配

    Android屏幕适配一直是一个头疼的问题.除此之外还要考虑APP在实际应用场景中,用户千奇百怪的设置,最常见的用户设置行为就是设置手机的字体大小,比如把字体设置成超大或者超小,这对屏幕适配又带来额外 ...

  9. 【转】Android屏幕适配全攻略(最权威的官方适配指导)

    原文网址:http://blog.csdn.net/jdsjlzx/article/details/45891551 Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的 ...

随机推荐

  1. Eclipse没有 web Project 选项的解决办法

    装下插件即可.步骤如下: 选择 Help >Software Updates >Find and Install.这个选项会让您可以下载和安装 Web 工具,且无需转到 Web 站点. 选 ...

  2. Java重构-策略模式、状态模式、卫语句

    前言 当代码中出现多重if-else语句或者switch语句时.弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处 ...

  3. Trees on the level UVA - 122 复习二叉树建立过程,bfs,queue,strchr,sscanf的使用。

    Trees are fundamental in many branches of computer science (Pun definitely intended). Current state- ...

  4. 关于web上文章移植伴随的样式问题

    好多朋友疑问,关于网页上的html文章在不同编辑器和页面之间复制黏贴时伴随的样式(如css)是否也一起被复制.这里统一回答下: 很多人遇见这种情况:网页上看到一篇内容充实主题明确,更重要的是样式精美的 ...

  5. 将bloomfilter(布隆过滤器)集成到scrapy-redis中

    Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如 ...

  6. 十年WEB技术发展历程

    一个小分享,知识有限,抛砖引玉. ajax 03年的时候我上六年级,那时候网吧刚在小县城的角落萌生.传奇,大话西游第一代网游一时风靡.我抱着试一试的心态给了网吧老板两块钱想申请个号玩玩,然后接下来的一 ...

  7. UFLDL深度学习笔记 (一)反向传播与稀疏自编码

    UFLDL深度学习笔记 (一)基本知识与稀疏自编码 前言 近来正在系统研究一下深度学习,作为新入门者,为了更好地理解.交流,准备把学习过程总结记录下来.最开始的规划是先学习理论推导:然后学习一两种开源 ...

  8. 嵌入式开发之davinci--- 8148/8168/8127 中swms、Mosaic’s、display 显示pal 模式

    (1) (2) (3) (4) -------------------------author:pkf ------------------------------time:2-3 --------- ...

  9. CentOS 6.5 Ruby源码安装

    清除旧版Ruby,若存在 yum remove ruby 若为源码,使用如下命令 cd <your-ruby-source-path> make uninstall 下面开始安装Ruby ...

  10. git undo last commit

    $ git commit -m "Something terribly misguided" (1) $ git reset --soft HEAD~ (2) << e ...