[Android][Android UI需要弄清楚的一些事]

来源:互联网 发布:mac优酷没有弹幕 编辑:程序博客网 时间:2024/05/16 02:46

1.下笔缘由

虽然一直从事Android开发,但是对于Android UI的许多概念和注意事项都了解得不是很透彻,因此希望通过这篇文章记录自己在解惑过程中找到的一下答案。

2.知识点的解释和需要注意的事项

1)分辨率

分辨率可以从显示分辨率与图像分辨率两个方向来分类。
显示分辨率(屏幕分辨率)是屏幕图像的精密度,是指显示器所能显示的像素有多少。
图像分辨率则是单位英寸中所包含的像素点数。
描述分辨率的单位有:(dpi点每英寸)、lpi(线每英寸)和ppi(像素每英寸)。但只有lpi是描述光学分辨率的尺度的。虽然dpi和ppi也属于分辨率范畴内的单位,但是他们的含义与lpi不同。而且lpi与dpi无法换算,只能凭经验估算。ppi和dpi经常都会出现混用现象。但是他们所用的领域也存在区别。从技术角度说,“像素”只存在于电脑显示领域,而“点”只出现于打印或印刷领域。点有时也用来表示像素,特别是计算机市场营销人员,多数时间使用DPI(dots per inch)表示。
上面是百度百科上对分辨率的解释,但是对于我来说下面这个解释更能让我理解和接受。分辨率是显示器能够示显的像素多少。(水平×垂直 如1024×768),上面说描述分辨率的单位有:(dpi点每英寸)、lpi(线每英寸)和ppi(像素每英寸),这种点每英寸的说法更像是密度的单位。我认为分辨率的单位应该是px,如1024*768px,而在计算机中,dpi和ppi单位是屏幕密度单位。

2)屏幕密度

屏幕物理区域中的像素量。正如上面所说的我觉得dpi(点每英寸)、lpi(线每英寸)和ppi(像素每英寸)这几个单位应该都是密度单位。在Android中,通常是使用DPI作为密度单位。网上有说,当DPI的概念用在计算机屏幕上时,就应称之为PPI(Pixels Per Inch)。同理: PPI就是计算机屏幕上每英寸可以显示的像素点的数量。这样看来,在计算机屏幕上,DPI和PPI基本上表示的是一个意思了。

3)像素

像素是指基本原色素及其灰度的基本编码。我的理解是对于图像,像素只是构成图像的一个基本单位,也就是一个基本的染色点。

4)Device independent Pixel(设备独立像素)

DP(叫DIP也行)就是Device independent Pixel(设备独立像素)的缩写。这个单位是Android提出的,DP定义 UI 布局时应使用的虚拟像素单位,用于以密度无关方式表示布局维度或位置。当屏幕密度等于 160 dpi 时,1dip相当于屏幕上的一个物理像素,160dpi是Android系统为“中”密度屏幕假设的基线密度。在运行时,系统根据使用中屏幕的实际密度按需要以透明方式处理 dp 单位的任何缩放 。dp 单位转换为屏幕像素很简单: px = dp * (dpi / 160)。 例如,在 240 dpi 屏幕上,1 dp 等于 1.5 物理像素。在定义应用的 UI 时应始终使用 dp 单位 ,以确保在不同密度的屏幕上正常显示 UI。

5)代码中设置的宽高是什么单位

在xml布局文件(layout)中,我们可以选择dp或者px作为单位。那么在代码(.java文件)中设置布局或控件的宽高使用的是什么单位呢?
答案是代码中设置的宽高的单位是px。
Android系统使用像素作为表示尺寸或坐标值的标准单位。这意味着, 视图的尺寸在代码中始终以像素表示,但始终基于当前的屏幕密度。 例如,如果 myView.getWidth() 返回 10,则表示视图在 当前屏幕上为 10 px宽,但在更高密度的屏幕上,返回的值可能是 15px。如果在应用代码中使用像素值来处理预先未针对 当前屏幕密度缩放的位图,您可能需要缩放代码中使用的像素值,以与未缩放的位图来源匹配。
在Android中,控件的宽高推荐使用DP单位。DP和PT是用来定义应用在不同设备、不同DPI下的标准单位。DP(叫DIP也行)就是Device independent Pixel(设备独立像素)的缩写,PT就是point。PT是Apple的东西,DP是Android的东西,其实就是一个人有两个名字。
SP跟DP不一样,但用法基本一样,SP是用来专门定义文字大小的。SP受用户Android设备字体设置的影响。

6)位图缩放造成的影响

首先明白什么是位图:位图亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。扩大位图尺寸的效果是增大单个像素,从而使线条和形状显得参差不齐。
如果将位图直接放大,是必然会出现模糊的,这是位图的基因带来的后果,不可避免,所以我们建议选择将大尺寸的内容缩小置于小画布,这里必须说明一点的是,将大尺寸的内容缩小也有可能会产生模糊。
产生的原因可能有:
1)没有用向量档
2)即使用了向量档,没有对齐像素
3)在设计的过程中尺寸上出现了小数(这种情况在手动缩放形状后经常产生)
4)旋转过图形

7)图片大小和图形大小的区别

图片大小和图形大小的区别分析图

在上图中,图片的大小为200px*200px,其中的图形大小却为113px*134px,也就是说图形大小<=图片大小。建议对于图标的设计,尽量保证图片背景为透明,以适用于各种背景环境。这个是很重要的,Android工程师在设置图片的时候,应该考虑到图片大小和图形大小的问题。

8)字体的大小应该注意的地方

关于字体的大小,Android官方提到,为不同控件引入字体大小上的反差有助于营造有序、易懂的排版效果。但在同一个界面中使用过多不同的字体大小则会造成混乱。官方的建议是使用12sp 14sp 18sp 22sp等字体大小。看到网上的一些资料还提及到,字体的大小尽量不要出现奇数。我觉得可能是因为如果在不同的屏幕密度小,有可能会造成字体大小出现小数,这时候系统就要进行四舍五入计算了。例如在160dpi上,字体的大小是13sp显示的就是13px,但是在240dpi上13*(240/160)= 19.5px。

9)Android状态栏在设计界面的时候需要考虑在内

Android状态栏

在安卓里,我们将其成为“状态栏”(styleBar),它的高度为25dp(这里的描述是针对mdpi而言),它一定是算在整个设计高度里的。

10)屏幕尺寸

指的是设备的物理尺寸,通常单位是英寸(inch,缩写为in.)。一般为1in=2.54cm。

3.在代码中获取屏幕密度等参数的例子

下面是关于在代码中获取屏幕密度等参数的例子,例子也分析了px和dp转换的方法,也就是px = dp * (dpi / 160)。而且我们需要注意的是Android对屏幕密度是使用了归化。
也就是谷歌将屏幕密度划分为六种通用的密度:
ldpi(低)~120dpi
mdpi(中)~160dpi
hdpi(高)~240dpi
xhdpi(超高)~320dpi
xxhdpi(超超高)~480dpi
xxxhdpi(超超超高)~640dpi
每种通用的尺寸和密度都涵盖一个实际屏幕尺寸和密度范围。也就是说如果你手机的真实屏幕密度是243dpi,那么Android系统是将手机真实的屏幕密度和上面六种通用密度进行对比,看看和哪一个通用密度值比较相近,就将它归入对应的通用密度。也就是说在进行px和dp单位转换的时候,Android系统是根据px = dp * (240 / 160)来转换的,而不是px = dp * (243 / 160)来计算。
另外,Google还将屏幕尺寸分为四种通用尺寸:小、正常、 大 和超大。但是从 Android 3.2(API 级别 13)开始,这些尺寸组已弃用,转而采用根据可用屏幕宽度管理屏幕尺寸的新技术。

说明 Android 如何将实际尺寸和密度粗略地 对应到通用的尺寸和密度(数据并不精确)

/** * @author LGY * px = dp * (dpi / 160) * <br> * 已知华为M2-A01L平板的dpi是224,但是根据谷歌归化原则,224属于240范畴;宽是1200px,高是1920px, * 根据公式,如果我希望控件占据屏幕高的一半,那么我们设置的dp值应该是多少?通过计算1920 = dp*(240/160), * 结果是1280dp,1280/2也就是屏幕的一半即640dp. */public class Test extends Activity{    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.test1);        //densityDpi即归化的DPI,我们知道华为M2-A01L平板的dpi是224,但是这个densityDpi是归化后的值240        Log.i("lgy", "DPI:"+getResources().getDisplayMetrics().densityDpi);        //即相当于在240dpi屏幕上,1dp=1.5px,这里的getResources().getDisplayMetrics().density值等于1.5        Log.i("lgy", "density:"+getResources().getDisplayMetrics().density);        //屏幕的宽,widthPixels=1200        Log.i("lgy", "widthPixels:"+getResources().getDisplayMetrics().widthPixels);        //屏幕的高,widthPixels=1920        Log.i("lgy", "heightPixels:"+getResources().getDisplayMetrics().heightPixels);        Log.i("lgy", "xdpi:"+getResources().getDisplayMetrics().xdpi);        Log.i("lgy", "ydpi:"+getResources().getDisplayMetrics().ydpi);        Log.i("lgy", "scaledDensity:"+getResources().getDisplayMetrics().scaledDensity);    }}

4.源码地址

http://download.csdn.net/download/lgywsdy/9993980

5.参考文章

https://developer.android.com/guide/practices/screens_support.html
http://www.cnblogs.com/JLZT1223/p/6784449.html
http://www.xueui.cn/design-theory/how-to-design-6.html
https://mirrors.segmentfault.com/adchs/index.html