[Xamarin.Android]不同分辨率下的 Layout 设计以及图片使用概论
设计 Android App 的时候, 其尺寸众多也是一个挑战之一. 要针对不同尺寸设计 Android App 时, 就要先来了一下 dpi(dots per inch, 每一英寸的点数量)与 ppi(pixel per square inch, 每平方英寸的像素量)计算方式. 这一篇研究就来讨论一下在设计 Android App, 如何因应不同的尺寸来作呈现.
n 首先 dpi 的定义是指每一英寸下, 有多少像素(pixel).
举例来说, 如果我的屏幕分辨率设定成 800X600pixel(72dpi),72dpi 的意思就是每一个英寸里面有 72 个像素(pixel). 所以先把屏幕分辨率换算成英寸,(800/72)X(600/72)pixel = 11.1X8.3(英寸).
n 屏幕的尺寸是如何计算公式
目前屏幕的尺寸是根据对角线的长度来定义. 所以套用到数学毕氏定理的对角线计算公式就是
[长平方 + 宽平方 = 斜边平方].
n ppi 计算公式(pixel per square inch, 每平方英寸的像素量)
ppi = √长度像素平方 + 宽度像素平方 ÷ 屏幕尺寸
接下来参考一下 Android 官方网站提供的分辨率尺寸对照图表, 这是 Android Device 不同分辨率对应到所存取的资源列表.
以分辨率 240x320 的手机来说, 若在 App 开发中有针对低分辨率的 Device 制作低分辨率的图片, 则系统就会使用 Low density 的图片.
*假设有一只屏幕规格为 3 吋而分辨率为 (240X320) 的手机, 那我们就可以推算出它的 ppi 值,
√240?2+320?2/3=133, 所以我们可以得到这个手机的 ppi 值是 133.
n Android 会自动根据你的手机尺寸来决定要用的图档是哪一个.
在设计支持多尺寸的 App 时, 可以设计让 Android 手机依照分辨率的不同来存取不同的资源.
在 Android 项目中, 图片资源是被放在 Drawable 数据夹下. 而我们可以依据不同的分辨率需求来制作相对应的图片资源, 让 Android 设备去读取适合他的图片资源. 在 Android 项目中 Resource 下的数据夹结构有下列几个数据夹, 分别是[drawable-ldpi],[drawable-mdpi],[drawable-hdpi] ,[drawable-xhdpi]
. 这几个数据夹是用来放置不同分辨率所相对应的图片资源文件.
再来看到这些图片的比较基准. 如果我们把放在 mdpi 数据夹下的图片当做基准, 假设这个图片的比例是 1 的话. 则存放在 ldpi 里面里的图片文件相对比例就是 0.75x. 而 hdpi 的相对应文件就是 1.5x, 以此类推.
- res/drawable-mdpi/my_icon.PNG // bitmap for medium density
- res/drawable-hdpi/my_icon.PNG // bitmap for high density
- res/drawable-xhdpi/my_icon.PNG // bitmap for extra high density
以 Android 官方网站提供的这个图表来看, 可以提供下列的比例参照方式去换算在制作图档时应该注意的尺寸比例.
- 36x36 for low-density
- 48x48 for medium-density
- 72x72 for high-density
- 96x96 for extra high-density
n 了解 Android 如何判断目前 Device 该用哪一个数据夹里面资源的方式
得知目前 Device 上的 Density.Density 数值是 Android Device 用来判断它该用哪一个数据夹下的资源.
可以用底下方法列出目前 Device 的 Density 值.
- var dp = Resources.DisplayMetrics.Density;
- Console.WriteLine ("density ="+ dp);
原生的 java 会是这样写
float scale = getApplicationContext().getResources().getDisplayMetrics().density;
下方式列出来的 Density 值对应到所参照的资源参考依据.
- 0.75 means low density
- 1.0 means standard (medium) density
- 1.5 means high (large) density
- 2.0 means extra high density
- ?
n 除了图片档外, layout 下的文件也是可以依照分辨率的不同来做区分
在 Android 架构中负责显示 layout 的 View 画面可以依据不同的分辨率来做不同的呈现.
参考下方, Android 有定义不同分辨率对应到的 layout 尺寸, 以及这个尺寸该被放在哪个相对应的数据夹下.
- res/layout/my_layout.xml // layout for normal screen size ("default")
- res/layout-small/my_layout.xml // layout for small screen size
- res/layout-large/my_layout.xml // layout for large screen size
- res/layout-xlarge/my_layout.xml // layout for extra large screen size
- res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation
- ?
n 在 AndroidManifest 文件新增支持不同分辨率 Device 的 xml 语法.
?
n 在 Xamarin studio 中针对不同的分辨率来建立相对应的 View 画面.
Xamarin Studio 的 Android 项目, 在 Layout 设计工具中, 在设计划面的左上角, 可以针对不同的分辨率尺寸新增 Layout 中的 View 画面. 然后可以经由点选默认的一些尺寸对应来 mapping 到不同分辨率的画面设计.
?
在编辑画面左边按下[Mulit-edit], 这三个 Layout 画面会被连结起来, 假如你拖拉一个 Button 进到其中一个画面里面, 三个 Layout 都会自动新增起一个 button 控件. 这样实在满方便的.
?
当你编译这个项目的时候, 可以看到 Xamarin 自动帮你建立出不同 layout 画面下的 Main.axml 文件.
?
n 依照不同的分辨率来放置图片资源文件
在 Android 的系统规范下, 不同分辨率的 Device 会自动存取适合自己分辨率的图片资源,
所以在设计图片文件的时候, 就需要针对不同的分辨率来设计图片. 而这些图片资源必须以相同的文件名称存在于不同的相对应的数据夹, 这样在 Android 执行你的 App 的时候, 会自动在相对应的路径下去存取适合他的图片.
?
n 在不同的分辨率下, 这边我新增了三个主要的控件, 两个文字标签以及一个 Imageview.
1. 第一个文字标签上面会在不同的 View 上显示 [手机],[平板],[大平板] 用来分辨我们现在到底载入了那一个 Layout 进来.
2. 第二个文字标签是要显示出目前 Device 的 Density, 来看看 Android 目前判断出来的 Device Density 值.
3. 而 ImageView 是用来载入图片, 这里 Android 系统会依据不同的 Device 分辨率来载入相对应的图片.
?
n 新增程序到对应 layout 的 Activtiy
虽然这边有三个不同的 layout 来对应不同分辨率的 Device, 但是实际上, 这三个 Layout 的名称都叫做 Main.axml. 并且里面的控制相名称也都相同, 这样你并不需要用程序来为不同的 Layout 做判断, 这部分的设计还真是很不错. 所以可以看到底下的程序, 在读取图片文件到 imageview 的时候, 这边不需要在程序上做任何判断.Android 会依照 Device 的分辨率来选择最适合它的图片资源.
?
n 在 Genymotion 模拟器中建立了建立三个不同分辨率的 Android Device 与我的实机一起来测试.
这四个不同分辨率与尺寸的设备分别如下
分辨率 (480x800,240dpi ) 的 Nexus One.
分辨率 (1024x600,160dpi) 的 WSVGA 7.0 Tablet.
分辨率 (1024x800,160dpi) 的 WXGA 10.1 Tablet.
分辨率 (1080x1776,480dpi) 的 Htc new one 实机.
?
n 编译程序
在 WXGA 10.1 Tablet 的模拟器上, 由于它的分辨率是 1280x800, 所以系统会自动抓到适合他的 layout.
在图片资源的部分, 这个模拟器的 dpi 是 160, 所以这边会抓到存放于 mdpi 里面的图片文件.
?
在 Nexus One 的模拟器上, 虽然它的分辨率是 480x800, 但是它的 dpi 值为 240,
在图片资源的部分, 它是自动抓取 Ldpi 数据夹里面的图片.
?
在我的手机上实测这支 App, 我手机的分辨率是 1080x1776, 而 dpi 值是 480, 在这个设备上, 他会取得 xhdpi 数据夹里面的图片支持.
?
n 最后在这边研究, 这边下一个结论.
Android 在判断该存取哪一个 layout 中的 View 以及那一个数据夹中的图片资源, 并不是单单由屏幕尺寸来判断. Android 实际在判断时会依据你的屏幕分辨率还有 dpi 值来做判断.
而分辨率影响的是会从那一个 Layout 取出相对应的 View 显示在设备的画面上.
而 dpi 值决定着 Android 会去哪一个数据夹里面参考资源.
参考数据:
- supports-screenssupports-screens
- http://developer.android.com/guide/topics/manifest/supports-screens-element.html
- Devices and Displays
- http://developer.android.com/design/style/devices-displays.html
- Supporting Multiple Screens
- http://developer.android.com/guide/practices/screens_support.html
- Devices and Displays
- http://developer.android.com/design/style/devices-displays.html
- Part 4 - Creating Resources for Varying Screens
- http://docs.xamarin.com/guides/android/application_fundamentals/resources_in_android/part_4_-_creating_resources_for_varying_screens/
- List of displays by pixel density
- http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
来源: http://www.bubuko.com/infodetail-3195820.html