書名: Android Studio開發實戰:從零基礎到App上線 (移動開發叢書)作者名: 歐陽燊本章字數: 2015字更新時間: 2020-11-28 17:31:37
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 某手機上的分辨率信息
- Pandas Cookbook
- 深入淺出Electron:原理、工程與實踐
- Apache Spark 2.x Machine Learning Cookbook
- 程序員面試算法寶典
- Mastering QGIS
- Android NDK Beginner’s Guide
- Koa開發:入門、進階與實戰
- Kotlin Programming By Example
- iOS開發項目化入門教程
- Mastering PowerCLI
- Android技術內幕(系統卷)
- Python數據可視化之matplotlib實踐
- Socket.IO Cookbook
- jQuery Essentials
- LiveCode Mobile Development Hotshot