android 屏幕适配

android 屏幕适配,第1张

@[TOC](文章目录)

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

# 前言

<font color=#999AAA >使用工具Android studio,利用values文件下dimensxml界面适配安卓屏幕</font>

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

<font color=#999AAA >提示:以下是本篇文章正文内容,下面案例可供参考

# 一、概念

1屏幕分辨率单位是px,例如Android手机常见的分辨率:320x480px、480x800px、720x1280px、1080x1920px。

2手机屏幕的密度:每英寸的像素点数,单位是dpi。

| 密度类型 |代表的分辨率(px)| 屏幕像素密度(dpi) | 1dp转换为px |

|:--------|:--------|:--------|:--------|

| 低密度(ldpi) |240x320|120|075|

| 中密度(mdpi) |320x480|160|1|

| 高密度(hdpi)|480x800|240| 15|

| 超高密度(xhdpi)|720x1280|320|2|

| 超超高密度(xxhdpi) |1080x1920|480|3|

3由于android的机型屏幕大小品类太多了,有一些是不标准的,这时我们就需要单独去获取屏幕的分辨率和密度了。

# 二、获取屏幕的分辨率和密度

```java

DisplayMetrics displayMetrics = getResources()getDisplayMetrics();

    float density = displayMetricsdensity;

    int densityDpi = displayMetricsdensityDpi;

    int width = displayMetricswidthPixels;

    int height = displayMetricsheightPixels;

    Loge("123","密度:"+density+"---"+densityDpi);

    Loge("123","屏幕分辨率:"+width+"x"+height);

    Loge("123","安卓系统:"+androidosBuildVERSIONRELEASE);

    Loge("123","手表型号:"+androidosBuildPRODUCT);

```

# 三、SmallestWidth适配

smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。

sw计算公式:sw = 屏幕宽度 / (dpi/160)  注:160是默认的

例如:屏幕宽度为1080px、480dpi 的sw = 1080/(480/160)

# 四、生成 dimens 文件

1、 首先在 res 目录下新建各种尺寸的 values 文件 。文件名为:values-sw(你要适配屏幕的sw值)dp。

例如:

![code23](>

ldpi(低)~120dpi

mdpi(中)~160dpi

hdpi(高)~240dpi

xhdpi(超高)~320dpi

xxhdpi(超超高)~480dpi

xxxhdpi(超超超高)~640dpi

dpi_examplepng

屏幕密度无关像素dp(dip)

Density Independent Pixels,即密度无关像素。

160dpi, 1dp = 1px

240dpi, 1dp = 15px

320dpi, 1dp = 2px

480dpi, 1dp = 3px

640dpi, 1dp = 4px

使用px在低、中、高屏幕密度下的效果

density-test-badpng

使用dp在低、中、高屏幕密度下的效果

density-test-goodpng

独立比例像素sp

Scale Independent Pixels, 即sp或sip。

Android开发时用此单位设置文字大小,可根据字体大小首选项进行缩放,推荐使用12sp、14sp、18sp、22sp作为字体设置的大小,不推荐使用奇数和小数,容易造成精度的丢失问题,小于12sp的字体会太小导致用户看不清。

屏幕适配之适配

screens-densitiespng

在设计图标时,对于5种主流的像素密度(mdpi,hdpi,xhdpi,xxhdpi和xxxdpi)应按照2:3:4:6:8的比例进行缩放。例如一个启动ic_launcherpng,它在各个像素密度文件夹下大小为:

ldpi(低)

mdpi(中)4848

hdpi(高)7272

xhdpi(超高)9696

xxhdpi(超超高)144144

xxxhdpi(超超超高)192192

存在的问题

每套分辨率出一套图,为美工或者设计增加了许多工作量

对Android工程文件的apk包变的很大

解决方法

Android SDK加载流程

Android SDK会根据屏幕密度自动选择对应的资源文件进行渲染加载,比如说,SDK检测到你手机的分辨率是xhdpi,会优先到xhdpi文件夹下找对应的资源;

如果xhdpi文件夹下没有资源,那么就会去分辨率高的文件夹下查找,比如xxhdpi,直到找到同名资源,将它按比例缩小成xhpi;

如果往上查找还是没有找到,那么就会往低分辨率的文件夹查找,比如hdpi,直到找到同名资源,将它按比例放大成xhpi。

根据加载的流程,可以得出理论上提供一套就可以了。

那么应该提供哪种分辨率规格呢?

原则上越高越好,同时结合当前主流分辨率屏幕

自动拉伸

ninepatch_rawpng

ninepatch_examplespng

屏幕适配之布局适配

布局参数

使用wrap_content, match_parent, layout_weight。

weight的使用

weight的计算

宽度 = 原来宽度   权重比值 剩余宽度

当layout_width为0dp,layout_weight分别是1和2

第一个按钮:宽度 = 0   1/3 屏宽 = 1/3屏宽

第二个按钮:宽度 = 0   2/3 屏宽 = 2/3屏宽

当layout_width为match_parent, layout_weight分别是1和2

第一个按钮:宽度 = 屏宽   1/3 (屏宽 - 2 屏宽) = 2/3屏宽

第二个按钮:宽度 = 屏宽   2/3 (屏宽 - 2 屏宽) = 1/3屏宽

布局使用

使用相对布局,禁用绝对布局。

限定符

尺寸限定符

在手机较小的屏幕上,加载layout文件夹布局

在平板电脑和电视的屏幕(>7英寸)上, 加载layout-large文件夹的布局

Android32版本之前

最小宽度限定符

在手机较小的屏幕上,加载layout文件夹布局

标准7英寸平板(其最小宽度为 600 dp),加载layout-sw600dp文件夹的布局

在Android32版本及之后版本

布局别名

适配手机的单面板(默认)布局:res/layout/activity_mainxml

适配尺寸>7寸平板的双面板布局(Android 32前):res/layout-large/activity_mainxml

适配尺寸>7寸平板的双面板布局(Android 32后):res/layout-sw600dp/activity_mainxml

最后的两个文件的xml内容是完全相同的,这会带来:文件名的重复从而带来一些列后期维护的问题,修改一个文件,可能忘记修改另外一个。于是为了要解决这种重复问题,我们引入了布局别名。

适配手机的单面板(默认)布局:res/layout/activity_mainxml

适配尺寸>7寸平板的双面板布局:res/layout/activity_twopanesxml

res/values/layoutxml

<xml version="10" encoding="utf-8">  <resources>      <item name="main" type="layout">@layout/activity_main</item>  </resources>

res/values-large/layoutxml

<xml version="10" encoding="utf-8">  <resources>      <item name="main" type="layout">@layout/activity_twopanes</item>  </resources>

res/values-sw600dp/layoutxml

<xml version="10" encoding="utf-8">  <resources>      <item name="main" type="layout">@layout/activity_twopanes</item>  </resources>

setContentView(Rlayoutmain);

屏幕方向限定符

res/layout-land

res/layout-port

res/layout-sw600dp-land

res/layout-sw600dp-port

屏幕适配之dimen适配

Nexus 4 (47英寸 768x1280:xhdpi)

dimen_example1png

Nexus S (4英寸 480x800:hdpi)

dimen_example2png

即使使用dp,依然不能解决屏幕分辨率的适配问题,我们可以针对不同的屏幕创建不同的dimen值。

它们的关系

像素密度与分辨率(P)像素密度=√{(长度像素数^2+宽度像素数^2)}/ 屏幕尺寸

举例:

小米官方数据显示MI3的屏幕像素密度,即PPI约为441。 

        MI3分辨率:1920x1080         屏幕尺寸:5英寸

       √1920²+1080²/5         (根号里面是1920²x1080²)

      =√3686400+1166400/5

      =√4852800/5

      ≈44058

      ≈441

两者间的区别

像素密度:即每英寸屏幕所拥有的像素数,像素密度越大,显示画面细节就越丰富。

逐行扫描:720P、1080P都是是一种视频显示格式,外语字母P意为逐行扫描,它是美国**电视工程师协会(SMPTE)制定的最高等级高清数字电视的格式标准,帧率通常为60Hz,可标示在p后面,如1080p30,意思是30Hz。常见的帧率还有24、25、30。并非HDMI就一定有1080p的输出,画面不一定要能支持1920×1080才能算是1080p输出,只要水平扫描线超过1080条就能称之为1080p,水平像素点并没有严格的规范,Full HD才是规范垂直与水平扫描像素的标准,1080p仅规范垂直像素点(等同水平扫描线)。

Android项目的res目录下一般加上我们自己创建的,会有6个目录,分别是:drawble drawble-ldpi drawble-mdpi drawble-hdpi drawble-xhdpi drawble-xxhdpi, 这里就不包括更为特殊的drawble目录了,(比如drawlbe-land-hdpi, 表示水平方向的高分辨率的,这些都目录不管多么长,它们都是按一丁点规律匹配的, 我们的目的是, 从个别中发现规律,从而应用到整体)。

当一个apk运行起来时,Android系统会根据其所运行的手机的屏幕密度去相对应的文件夹里找指定名称的。 注意, 先去哪个目录里找,完全是根据这个手机的屏幕密度决定的。

其中注意两点:

1, 中等分辨率,即mdpi的屏幕密度是160,他是标准的参考密度。所以计算比例的时候它的比例值是1 其他屏幕密度的参考比例都是以这个为依据。

2, 默认的drawble目录(一般是自己建的),和mdpi是一样的。将放到这个目录和放到drawble-mdpi目录是一样的效果。不过一般习惯性的放一些自定义selector或者点9的在这里。

现在我们来看, HTC one V手机的屏幕密度是252ppi, 那距离哪一个最靠近呢, 就是hdpi了。 所以当apk运行在这个手机上时,首先会去这个目录找。

下面是用常见的一些类型的手机总结的一个表格:

注意一点: 上面说的对应关系,都是首选目录, 那如果首选目录里面找不到呢?

Android选择策略

上面说到, 如果屏幕所对应的文件夹没有要找的,怎么办。这是很常见的,我们开发项目时一般不会去为每一个级别的屏幕去切一套。那样做只会让apk很大。所以一般性的我们只切一两个典型密度屏幕的。但是apk是有可能会运行在从ldpi到xxhdpi的各种级别的手机上。这个时候就需要根据一定的策略去寻找了。

Android系统寻找的步骤是这样的:

1, 去屏幕密度对应的目录去找。如果找到就拿来用。

2, 如果没找到,就去比这个密度高一级的目录里面去找,如果找到就拿来用。

3, 如果没找到就继续往上找。以此类推。

4, 如果到了xxhdpi目录还没有找到的话,就会去比自身屏幕密度低一级的目录去找,如果低一级的目录>=hdpi,找到了就拿来用。

5, 如果没找到, 就去mdpi目录去找, 如果找到了,就拿来用。

6, 如果没找到,就去默认的drawble目录里去找, 如果找到了就拿来用。

7 ,如果没找到,再去最低的ldpi目录里去找。如果找到了,就拿来用。

8, 如果没找到, 那就是没找到了, 无法显示。(不过一般不会出现这种现象,因为如果每个目录都没有这个的话,你是编译不过的)

这里有两点需要注意:

① 首先会去比自己密度高的目录里去找,这是因为因为系统相信,你在密度更高的目录里会放置分辨率更大的,这样的话这个会被缩小,但同时显示效果不会有损失,但是如果优先去低一级别的目录去找的话, 找到的就会被放大,这样的话这个就会被拉扯模糊了。

eg 同一张,你在mdpi和xxhdpi目录各放了一份, 这个应用你现在运行在hdpi的手机上, 那应用会选择哪张呢。答案是xxhdpi目录里的。即便hdpi离mdpi更近一点!

②,如果在mdpi里找不到是不会直接去ldpi里找的, 而是先去默认的drawble目录里找,这是drawble目录和drawble-mdpi是一个级别的。

下面用一张流程图来总结:

(注: 以上流程图是我通过做实验总结出来的,如有谬误还望指出。)

Android系统对的缩放规则

上文中提到如果在手机对应的目录没有找到,就会按照一定的策略去其他目录找,那找到了以后就原图显示么? 非也。

对于放在不同目录下的, 系统会按照一定比例对原始的进行放大或者缩小, 具体的放大缩小比例可参考下表, 所在目录和对应的屏幕密度是相同时缩放比例为1,也就是原图显示,而横向的比例表示分别放在该密度手机上运行时被缩放的比例。

对原始的缩放倍数。

上表几点值得注意的地方:

①, drawable目录和drawable-mdpi目录和dp到px的转换关系是一样的。

②,当你放一个120px180px的到drawable-hdpi目录,如果此应用运行在一个xhdpi的手机上,则这个会被拉扯到160px240px。

③, 最后一行dp->px, 说明了在代码或者布局文件中声明一个dp值, 这个值在不同屏幕密度的手机中会被乘以不同的倍数。 比如你在布局文件中写了一个宽和高分别为120dp和180dp的LinearLayout, 那么当这个应用运行在xhdpi的手机上时(比如上面那个常见手机表中的中兴U985手机),它的实际像素就会被转换为240px360px。 如果运行在ldpi的手机上,就变成了90px135px。 但是在这两个手机中显示的区域大小从肉眼看,是一模一样大的。(这点作为后面内容的一个引子,“看起来”一样大,这就是Android的一个神奇的地方)

我们来做个试验

试验材料:

① 一张120px180px的

② 四部手机, 具体参数参考上面的一张表格。三星 Galaxy win pro 3218 (hdpi)、 HTC one V (hdpi)、 中兴U985 (xhdpi)、Google Nexus 7 (xhdpi)。

③ 我在布局文件里声明了3个View, 第一个位于左上角,是一个线性布局,宽和高指定为120dp180dp(注意是dp哦), 第二个位于右上角,是一个ImageView,内容就是上面这张120px180px的, 第三个位于左下角也是一个线性布局,固定宽高,是120px180px。

我将这个放到一个Android工程里的drawable-hdpi目录

从上面的那种缩放关系表中我们可以知道,从hdpi目录中取, 运行在hdpi手机上宽高保持原始值,,运行在xhdpi手机上,宽高会乘以4/3, 也就是说会被拉扯变大, 但是的实际显示效果,即“视觉大小”怎么样呢。

下面是运行后的效果:

如图: 黑色区域是120dp180dp的View, 蓝色区域是120px180px的, 灰色区域是120px120px的View。

1, 可以看到使用dp的View(黑色区域)在不同分辨率,不同屏幕尺寸,不同屏幕密度的手机下,视觉大小看起来是一模一样的。

但是他们的实际像素值是不一样的: 120dp180dp -> (hdpi) -> 180px270px, 而120dp180dp ->(xhdpi)-> 240px360px。 由于屏幕密度的不同,缩放以后的像素可以显示出一样的视觉大小。

2, 蓝色的视觉大小也是一样的, 由于放到了hdpi目录下, 所以前两个手使用的是的原始像素120px180px, 而后两个手机对进行了放大, 参考上面的屏幕密度缩放关系表, 放大了4/3倍。 我通过对屏幕的截图,测量下来的结果的确是放大了这么多, 分别为160px240px。 由于屏幕密度的不同,它们显示出来的视觉大小是相同的。

3, 但是使用固定像素值的View就没那么幸运了, 它在hdpi的手机上看起来要比在xhdpi的手机上大一些。 要是在屏幕密度相差更大的手机上看的话, 这个区域的大小会相差很大。 这就是为什么Android推荐使用dp作为View的尺寸,而不是真实像素的原因了。

4, 经过反复试验,(实验结果就不贴图了,很多),得出一个结论,使用哪个目录下的(前提是只放在某一个目录中),在所有,不管是分辨率还是屏幕尺寸还是屏幕密度,3个参数都在改变的情况下,显示的视觉大小都和运行在这个目录对应屏幕密度手机上时的大小是一样的。

UI给工程师切多大图是合适的。

说说我之前走的冤枉路吧。

在之前, 设计师的交互和视觉设计都是基于480800的界面, 切图的时候会以480800为基础切一版, 然后在给所切的宽和高乘上个4/3,然后在出一版。

比如同一个120180的, 就会出两个版本, 一个是120180的一个是160240的。分别放到hdpi目录和xhdpi目录。

吃到的苦头是,UI很累, apk很大。T^T

这番探究下来, 发现直接基于7201280的视觉稿切一版就可以了。 将只放到xhdpi目录中,这样系统会在不同密度屏幕的手机中对进行合理的缩放, 而之前这个缩放工作竟然是人工完成的!

另: 如果想在xxhdpi的手机上显示的很好, 也可以基于1080P的屏幕设计, 这样的话就兼容所有低密度屏幕的手机, 而且也不会出现被拉扯的现象。

以上就是关于android 屏幕适配全部的内容,包括:android 屏幕适配、Android屏幕适配的哪些事、Android设备的屏幕像素密度和720P,1080P的关系是怎么样的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9351226.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存