- Android Studio开发实战:从零基础到App上线 (移动开发丛书)
- 欧阳燊
- 2015字
- 2020-11-28 17:31:38
2.1 屏幕显示
本节从最基础的显示单元开始介绍,讲述了移动设备如何在屏幕上展现丰富多彩的界面。本节主要内容包括像素的几个常用单位、颜色的编码与使用、屏幕分辨率的获取等。
2.1.1 像素
老子曾说“天下难事必作于易,天下大事必作于细”, Android开发也是如此。纵使App的界面千变万化、绚丽多姿,也都归因于数百万个像素的组合排列,就像万物皆由原子构成一般。像素看似简单,实际有大学问,如果对像素单位不知其所以然,开发时只知一根筋的填数字,结果在模拟器上运行得很好的界面,在真机上很可能显示得东倒西歪,这就是没打好基础的缘故。如果一开始就把像素的基本概念弄清楚,后面就会少走很多弯路,开发起来也会更加得心应手。
Android支持的像素单位有:px(像素)、in(英寸)、mm(毫米)、pt(磅,1/72英寸)、dp(与设备无关的显示单位)、dip(就是dp)、sp(用于设置字体大小)。其中,常用的有px、dp和sp三种。
具体来说,px是手机屏幕上可显示的最小单位,与物理设备的显示屏有关。一般来说,同样尺寸的屏幕(比如5寸的手机)看起来越清晰,像素的密度越高,以px计量的分辨率也越大。
dp与物理设备无关,只与屏幕的尺寸有关。一般来说,同样尺寸的屏幕以dp计量的分辨率是一样的,无论这个手机是哪个厂家生产的,dp大小都一样。
sp的原理跟dp差不多,专门用于设置字体大小。手机在系统设置里可以调整字体的大小(小、普通、大、超大)。设置普通字体时,同数值dp和sp的文字看起来一样大;如果设置为大字体,用dp设置的文字没有变化,用sp设置的文字就变大了。例如,当系统设置普通字体时,18dp与18sp的文字一样大,如图2-1所示;当系统设置大字体时,18dp的文字大小不变,18sp的文字却增大了,如图2-2所示。
图2-1 普通字体的效果图
图2-2 大字体的效果图
所以说,dp与系统设置的字体大小没有关系,而sp会随系统设置的字体大小变大或变小。
dp和px之间的联系取决于具体设备上的像素密度,像素密度就是DisplayMetrics里的density参数。当density=1.0时,表示一个dp值对应一个px值;当density=1.5时,表示两个dp值对应3个px值;当density=2.0时,表示一个dp值对应两个px值。具体的转换函数如下:
public class Utils { //根据手机的分辨率从dp的单位转成为px(像素) public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } //根据手机的分辨率从px(像素) 的单位 转成为dp public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } }
在XML布局文件中,为了让不同设备屏幕拥有统一的显示效果,除了sp用于设置文字大小外,其余要用大小的地方都用dp。在代码中情况又有所不同,Android用于设置大小的函数都以px为单位。无论是LayoutParams里的width和height,还是setMargins和setPadding,参数单位都是px,要想在代码中使用dp设置布局大小或间距,得先把dp值转换成px值。代码示例如下:
int dip_10 = Utils.dip2px(this, 10L); TextView tv_padding = (TextView) findViewById(R.id.tv_padding); tv_padding.setPadding(dip_10, dip_10, dip_10, dip_10);
2.1.2 颜色
在Android中,颜色值由透明度alpha和RGB(红、绿、蓝)三原色定义,有八位十六进制数与六位十六进制数两种编码,例如八位编码FFEEDDCC, FF表示透明度,EE表示红色的浓度,DD表示绿色的浓度,CC表示蓝色的浓度。透明度为FF表示完全不透明,为00表示完全透明。RGB三色的数值越大颜色越浓也就越亮,数值越小颜色越暗。亮到极致就是白色,暗到极致就是黑色,这样记就不会搞混了。
六位十六进制编码有两种情况,在XML文件中默认不透明(透明度为FF),在代码中默认透明(透明度为00)。下面的代码分别给两个文本控件设置六位编码和八位编码的背景色。
TextView tv_code_six = (TextView) findViewById(R.id.tv_code_six); tv_code_six.setBackgroundColor(0x00ff00); TextView tv_code_eight = (TextView) findViewById(R.id.tv_code_eight); tv_code_eight.setBackgroundColor(0xff00ff00);
从图2-3可以看到,代码使用六位编码看不到任何背景,使用八位编码能够看到正确的绿色背景。
图2-3 不同方式设置颜色编码的效果图
在Android中使用颜色有下列3种方式:
1.使用系统已定义的颜色常量。
Android系统有12种已经定义好的颜色,具体的类型定义在Color类中,详细的取值说明见表2-1。
表2-1 颜色类型的取值说明
2.使用十六进制的颜色编码。
在布局文件中设置颜色需要在色值前面加“#”,如android:textColor="#000000"。在代码中设置颜色可以直接填八位的十六进制数值(如setTextColor(0xff00ff00);),也可以通过Color.rgb(intred,intgreen,intblue)和Color.argb(intalpha,intred,intgreen,intblue)这两种方法指定颜色。在代码中一般不要用六位编码,因为六位编码在代码中默认透明,所以代码用六位编码跟不用没什么区别。
3.使用colors.xml中定义的颜色。
res/values目录下有个colors.xml文件,是颜色常量的定义文件。如果要在布局文件中使用XML颜色常量,可引用“@color/常量名”;如果要在代码中使用XML颜色常量,可通过这行代码获取:getResources().getColor(R.color.常量名)。
2.1.3 屏幕分辨率
在App编码中时常要取手机的屏幕分辨率(如当前屏幕的宽和高),然后动态调整界面上的布局。在代码中获取分辨率就是想办法获得DisplayMetrics对象,然后从该对象中获得宽度、高度、像素密度等信息。下面是DisplayMetrics类的常用属性说明。
● widthPixels:以px为单位计量的宽度值。
● heightPixels:以px为单位计量的高度值。
● density:像素密度,即一个dp单位包含多少个px单位。
下面是获取当前屏幕的宽度、高度、像素密度的代码示例。
public class DisplayUtil { public static int getSreenWidth(Context ctx) { WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(dm); return dm.widthPixels; } public static int getSreenHeight(Context ctx) { WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(dm); return dm.heightPixels; } public static float getSreenDensity(Context ctx) { WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(dm); return dm.density; } }
从一个接入设备上获得屏幕分辨率信息,如图2-4所示。该设备为5寸屏幕,分辨率是720*1280,像素密度是2。
图2-4 某手机上的分辨率信息