1.屏幕尺寸信息
屏幕大小:屏幕對角線長度,單位“寸”;
分辨率:手機屏幕像素點個數,例如720x1280分辨率;
PPI(Pixels Per Inch):即DPI(Dots Per Inch),它是對角線的像素點數除以屏幕大小得到的;
系統屏幕密度:android系統定義了幾個標准的DPI值作為手機的固定DPI。(注,最后一個有筆誤,正確的是1080x1920)
獨立像素密度(DP):android系統使用mdpi屏幕作為標准,在這個屏幕上1dp=1px,其他屏幕可以通過比例進行換算。在hdpi中,1dp=1.5px。在xhdpi中,1dp=2px。在xxhdpi中,1dp=3px。
單位轉換:常用的單位轉換的輔助類DisplayUtil
/** |
2.2D繪圖基礎
(1)Canvas對象drawPoint,drawLine,drawRect,drawRoundRect,drawCircle,drawArc,drawOval,drawText,drawPosText(在指定位置繪制文本),drawPath(繪制路徑)
(2)Paint對象setAntiAlias:設置畫筆的鋸齒效果setColor:設置畫筆的顏色setARGB:設置畫筆的A、R、G、B值setAlpha:設置畫筆的透明度值setTextSize:設置字體大小setStyle:設置畫筆的效果(空心STROKE或者實心FILL)setStrokeWidth:設置空心邊框的寬度
3.Android XML繪圖
(1)Bitmap
在XML中定義Bitmap的語法
<?xml version="1.0" encoding="utf-8"?> |
(2)Shape
在XML中定義Shape的語法
<?xml version="1.0" encoding="utf-8"?> |
(3)Layer
在XML中定義Layer的語法,layer類似PS中圖層的概念,語法如下
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
(4)Selector
selector的用法很多,一般是定義控件在不同狀態下的顯示形態,可以是圖片drawable,也可以是形狀shape,還可以只是顏色color!
<?xml version="1.0" encoding="utf-8" ?> |
selector與shape結合的例子
<?xml version="1.0" encoding="utf-8"?> |
selector可以用來指定不同狀態下文本的顏色,例如按鈕上的文本的顏色
<?xml version="1.0" encoding="utf-8"?> |
結合這篇博文Android開發:shape和selector和layer-list以及博主的實現的圓角鏤空按鈕例子(綜合使用了Shape、Layer和Selector實現了圓角鏤空按鈕)一起看還是挺不錯的。
4.Android繪圖技巧
(1)Canvas 畫布
四個主要方法:save:保存畫布,將之前繪制的內容保存起來;restore:合並畫布,將save方法之后繪制的內容與之前繪制的內容合並起來;translate:移動畫布,其實是畫布所在的坐標系的移動;rotate:旋轉畫布,其實是畫布所在的坐標系的旋轉。
后面兩個方法主要是用來方便在某些特殊情況下的繪制,例如書中介紹的儀表盤的繪制
@Override |
(2)Layer 圖層
在Android中圖層是基於棧的結構來管理的,通過調用saveLayer、saveLayerAlpha方法來創建圖層,使用restore、restoreToCount方法將一個圖層入棧。入棧的時候,后面所有的操作都發生在這個圖層上,而出棧的時候則會把圖像繪制在上層Canvas上。
@Override |
儀表盤和Layer圖層效果如下:

5.Android圖像處理 [TODO:該部分略過了,自己暫時用的比較少,等需要用的時候學習下再補充]
色彩特效處理、圖形特效處理、畫筆特效處理
6.SurfaceView
SurfaceView與View的區別
(1)View主要適用於主動更新的情況下,而SurfaceView主要適用於被動更新,例如頻繁地刷新;
(2)View在主線程中對畫面進行刷新,而SurfaceView通常會通過一個子線程來進行頁面刷新;
(3)View在繪圖時沒有使用雙緩沖機制,而SurfaceView在底層實現機制中就已經實現了雙緩沖機制。
SurfaceView的使用
(1)創建SurfaceView,一般繼承自SurfaceView,並實現接口SurfaceHolderCallback。
SurfaceHolderCallback接口的三個回調方法
@Override |
(2)初始化SurfaceView
初始化SurfaceHolder對象,並設置Callback
private void initView() { |
(3)使用SurfaceView
通過lockCanvas方法獲取Canvas對象進行繪制,並通過unlockCanvasAndPost方法對畫布內容進行提交
需要注意的是每次調用lockCanvas拿到的Canvas都是同一個Canvas對象,所以之前的操作都會保留,如果需要擦除,可以在繪制之前調用drawColor方法來進行清屏。
private void draw() { |
書中使用SurfaceView實現了簡易畫板
public class SimpleDraw extends SurfaceView implements SurfaceHolder.Callback, Runnable { |
Android動畫機制與使用技巧
1.View動畫 (視圖動畫)
視圖動畫(Animation)框架定義了透明度(AlphaAnimation)、旋轉(RotateAnimation)、縮放(ScaleAnimation)和位移(TranslateAnimation)幾種常見的動畫,控制的是整個View,所以視圖動畫的缺陷就在於當某個元素發生視圖動畫后,其響應事件的位置還依然停留在原來的地方!
實現原理是每次繪制視圖時View所在的ViewGroup中的drawChild方法獲取該View的Animation的Transformation值,然后調用canvas.concat(transformationToApply.getMatrix()),通過矩陣運算完成動畫幀。如果動畫沒有完成,就繼續調用invalidate方法,啟動下次繪制來驅動動畫,從而完成整個動畫的繪制。
動畫集合(AnimationSet):將多個視圖動畫組合起來
動畫監聽器(AnimationListener):提供動畫的監聽回調方法
2.屬性動畫
Android 3.0之后添加了屬性動畫(Animator)框架,其中核心類ObjectAnimator能夠自動驅動,在不影響動畫效果的情況下減少CPU資源消耗。
ObjectAnimator
創建ObjectAnimator只需通過它的靜態工廠方法直接返回一個ObjectAnimator對象,參數包括view對象,以及view的屬性名字,這個屬性必須要有get/set方法,因為ObjectAnimator內部會通過反射機制來修改屬性值。常用的可以直接使用屬性動畫的屬性包括:
(1)translationX和translationY:控制view從它布局容器左上角坐標偏移的位置;
(2)rotation、rotationX和rotationY:控制view圍繞支點進行2D和3D旋轉;
(3)scaleX和scaleY:控制view圍繞着它的支點進行2D縮放;
(4)pivotX和pivotY:控制支點位置,圍繞這個支點進行旋轉和縮放處理。默認情況下,支點是view的中心點;
(5)x和y:控制view在它的容器中的最終位置,它是最初的左上角坐標和translationX、translationY的累計和;
(6)alpha:控制透明度,默認是1(不透明)。
ObjectAnimator的常見使用方式如下:
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 300); |
屬性動畫集合AnimatorSet:控制多個動畫的協同工作方式,常用方法animatorSet.play().with().before().after()、playTogether、playSequentially等方法來精確控制動畫播放順序。使用PropertyValueHolder也可以實現簡單的動畫集合效果。
動畫監聽器:監聽動畫事件可以使用AnimatorListener或者簡易的適配器AnimatorListenerAdapter
如果一個屬性沒有get/set方法怎么辦?
(1)自定義包裝類,間接地給屬性提供get/set方法,下面就是一個包裝類的例子,為width屬性提供了get/set方法
public class WrapperView { |
(2)使用ValueAnimator
ObjectAnimator就是繼承自ValueAnimator的,它是屬性動畫的核心,ValueAnimator不提供任何動畫效果,它就是一個數值產生器,用來產生具有一定規律的數字,從而讓調用者來控制動畫的實現過程,控制的方式是使用AnimatorUpdateListener來監聽數值的變換。
ValueAnimator animator = ValueAnimator.ofFloat(0,100); |
在XML中使用屬性動畫
下面是一個簡單例子:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" |
在代碼中使用方式如下: [注:測試該代碼的時候,上面的xml定義應該放在res的animator目錄下,放在anim目錄下不行]
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.animator_rotation); |
View的animate方法
Android 3.0之后View新增了animate方法直接驅動屬性動畫,它其實是屬性動畫的一種簡寫方式
imageView.animate().alpha(0).y(100).setDuration(1000) |
3.布局動畫
布局動畫是作用在ViewGroup上的,給ViewGroup添加view時添加動畫過渡效果。
(1)簡易方式(但是沒有什么效果):在xml中添加如下屬性 android:animateLayoutChanges="true
(2)通過LayoutAnimationController來自定義子view的過渡效果,下面是一個常見的使用例子:
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll); |
4.自定義動畫
創建自定義動畫就是要實現它的applyTransformation的邏輯,不過通常還需要覆蓋父類的initialize方法來實現初始化工作。
下面是一個模擬電視機關閉的動畫,
public class CustomTV extends Animation { |
applyTransformation方法的第一個參數interpolatedTime是插值器的時間因子,取值在0到1之間;第二個參數Transformation是矩陣的封裝類,一般使用它來獲得當前的矩陣Matrix對象,然后對矩陣進行操作,就可以實現動畫效果了。
如何實現3D動畫效果呢?
使用android.graphics.Camera中的Camera類,它封裝了OpenGL的3D動畫。可以把Camera想象成一個真實的攝像機,當物體固定在某處時,只要移動攝像機就能拍攝到具有立體感的圖像,因此通過它可以實現各種3D效果。
下面是一個3D動畫效果的例子
public class CustomAnim extends Animation { |
5.Android 5.X SVG矢量動畫機制 [TODO:該部分略過了,自己暫時用的比較少,等需要用的時候學習下再補充]
本章最后還有幾個很常用的動畫實例,感興趣可以看下。
