Android的繪圖機(jī)制是Android最核心的內(nèi)容之一,不管是什么樣的功能冲泥,最終都要以圖像的形式呈現(xiàn)給用戶氧猬。因此,掌握Android的繪圖技巧柳琢,可以讓你在設(shè)計(jì)應(yīng)用時更加隨心所欲绍妨,對Android的理解層次也會越來越高润脸。
一、屏幕的尺寸信息
- 屏幕大小
指屏幕對角線的長度他去,通常使用“寸”來度量毙驯,例如4.7寸手機(jī)、5.5寸手機(jī)等灾测。
- 分辨率
指手機(jī)屏幕的像素點(diǎn)個數(shù)爆价,例如720x1280就是指屏幕的分辨率,即寬有720個像素點(diǎn)媳搪,而高有1280個像素點(diǎn)铭段。
- PPI
每英寸像素(Pixels Per Inch),又被稱為DPI(Dots Per Inch)秦爆。它是由對角線的像素點(diǎn)數(shù)除以屏幕大小得到的序愚,通常達(dá)到400PPI就已經(jīng)是非常高的屏幕密度了。
幾個標(biāo)準(zhǔn)的DPI值
密度 | ldpi | mdpi | hdpi | xhdpi | xxhdpi |
---|---|---|---|---|---|
密度值 | 120 | 160 | 240 | 320 | 480 |
分辨率 | 240x320 | 320x480 | 480x800 | 720x1280 | 1080x1920 |
- 獨(dú)立像素密度dp
由于不同屏幕密度的存在鲜结,Android系統(tǒng)使用mdpi即密度值為160的屏幕作為標(biāo)準(zhǔn)展运,在這個屏幕上
1px=1dp
。其他屏幕則可以通過比例進(jìn)行換算精刷。各個分辨率的屏幕直接的換算比例為ldpi:mdpi:hdpi:xhdpi:xxhdpi=3:4:6:8:12
拗胜。
二、2D繪圖基礎(chǔ)
系統(tǒng)通過提供的Canvas對象來提供繪圖方法怒允,它提供了各種繪制圖像的API埂软,如drawPoint()、drawLine()纫事、drawRect()勘畔、drawVertices()、drawArc()丽惶、drawCircle()等等炫七。
畫筆Paint對象作為一個重要的元素,功能也是很強(qiáng)大的钾唬,這里簡單地列舉了一些它的屬性和對應(yīng)的功能万哪。
- setAntiAlias(); // 設(shè)置畫筆的鋸齒效果
- setColor(); // 設(shè)置畫筆的顏色
- setARGB(); // 設(shè)置畫筆的A、R抡秆、G奕巍、B值
- setAlpha(); // 設(shè)置畫筆的Alpha值
- setTextSize(); // 設(shè)置字體的尺寸
- setStyle(); // 設(shè)置畫筆的風(fēng)格(空心或?qū)嵭模?/li>
- setStrokeWidth(); // 設(shè)置空心邊框的寬度
結(jié)合Paint的不同設(shè)置和Canvas的不同的繪圖API,任意組合就可以實(shí)現(xiàn)不同的繪圖效果儒士。
三的止、Android XML繪圖
XML在Android系統(tǒng)可不僅僅是Java中的一般布局文件、配置列表着撩。在Android開發(fā)者的手上诅福,它甚至可以變成一張畫匾委、一幅圖。Android的開發(fā)者給XML提供了幾個強(qiáng)大的技能來幫助我們實(shí)現(xiàn)這一功能权谁。
- Bitmap
在XML中使用Bitmap非常簡單剩檀,代碼如下所示憋沿。
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher" />
通過這樣引用圖片旺芽,就可以將圖片直接轉(zhuǎn)成了Bitmap讓我們在程序中使用。
- Shape
通過Shape可以在XML中繪制各種形狀下面展示了Shape所支持的參數(shù)辐啄。
<shape xmlns:android=http://schemas.android.com/apk/res/android
android:shape=["rectangle" | "oval" | "line" | "ring"] > // 默認(rèn)為rectangle
<corners // 當(dāng)shape="rectangle"時使用
android:radius="integer" // 半徑采章,會被后面的單個半徑屬性覆蓋,默認(rèn)為1dp
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient // 漸變
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:useLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size // 指定大小壶辜,一般用在imageview配合scaleType屬性使用
android:width="integer"
android:height="integer" />
<solid // 填充顏色
android:color="integer" />
<stroke // 指定邊框
android:width="color"
android:color="color"
android:dashWidth="integer" // 虛線寬度
android:dashGap="integer" /> // 虛線間隔寬度
</shape>
Shape可以說是XML繪圖的精華所在悯舟。Shape功能十分強(qiáng)大,無論是扁平化砸民、擬物化還是漸變抵怎,它都能繪制。整個Shape的可用參數(shù)岭参,在上面的表中已經(jīng)列舉的很清楚了反惕。
- Layer
Layer是在Photoshop中非常常用的功能。在Android中演侯,同樣可以通過Layer來實(shí)現(xiàn)類似Photoshop中圖層的概念姿染。
- Selector
Selector的作用在于幫助開發(fā)者實(shí)現(xiàn)靜態(tài)繪圖中的事件反饋,通過給不同的事件設(shè)置不同的圖像秒际,從而在程序中根據(jù)輸入悬赏,返回不同的效果。
四娄徊、Android繪圖技巧
掌握Android的常用繪圖技巧闽颇,可以用來簡化、優(yōu)化Android的繪圖操作寄锐。常用的繪圖技巧涉及到Canvas兵多、Layer等對象,這里簡單介紹一下Canvas锐峭。
在這之前中鼠,首先來了解一下Android繪圖的坐標(biāo)體系。在Android中沿癞,默認(rèn)的坐標(biāo)零點(diǎn)位于屏幕的左上角援雇,向下為Y軸正方向,向右為X軸正方向椎扬。
Canvas作為繪制圖形的直接對象惫搏,提供了一下幾個非常有用的方法具温。
- Canvas.save()
- Canvas.restore()
- Canvas.translate()
- Canvas.rotate()
Canvas.save()這個方法,從字面上可以理解為保存畫布筐赔。它的作用就是將之前的所有已繪制圖像保存起來铣猩,讓后續(xù)的操作就好像在一個新的圖層上操作一樣,這一點(diǎn)與Photoshop中的圖層理解基本一致茴丰。
Canvas.restore()這個方法达皿,則可以理解為Photoshop中的合并圖層操作。它的作用是將我們在save()之后繪制的所有圖像與svae()之前的圖像進(jìn)行合并贿肩。
translate()方法和rotate()方法可以理解為畫布平移峦椰、畫布翻轉(zhuǎn),即坐標(biāo)系的平移和翻轉(zhuǎn)汰规。例如汤功,translate(x, y)就是將原點(diǎn)(0, 0)移動到了(x, y),之后的所有繪圖操作都將以(x, y)為原點(diǎn)執(zhí)行溜哮。
五滔金、View與SurfaceView的區(qū)別
為了避免自定義View的繪制過程中,處理邏輯太多導(dǎo)致主線程被阻塞茂嗓、畫面卡頓的問題餐茵,Android系統(tǒng)提供了SurfaceView組件。SurfaceView可以說是View的孿生兄弟在抛,但它與View還是有所不同的钟病,它們的區(qū)別主要體現(xiàn)在一下幾點(diǎn)。
- View主要使用與主動更新的情況下而SurfaceView主要使用于被動更新刚梭,例如頻繁地刷新肠阱。
- View在主線程中對畫面進(jìn)行刷新,而SurfaceView通常會通過一個子線程來進(jìn)行頁面的刷新朴读。
- View在繪圖時沒有使用雙緩沖機(jī)制屹徘,而SurfaceView在底層實(shí)現(xiàn)機(jī)制中就一斤實(shí)現(xiàn)了雙緩沖機(jī)制。
總之一句話衅金, 如果自定義View需要頻繁地刷新噪伊,或者刷新時處理量比較大,那么就可以考慮使用SurfaceView來取代View了氮唯。