# 8.4.3 Android動畫合集之屬性動畫-初見
## 本節引言:
本節給帶來的是Android動畫中的第三種動畫——屬性動畫(Property Animation), 記得在上一節[8.4.2 Android動畫合集之補間動畫](http://www.runoob.com/w3cnote/android-tutorial-alphaanimation.html "8.4.2 Android動畫合集之補間動畫")為Fragment 設置過渡動畫的時候,說過,App包和V4包下的Fragment調用setCustomAnimations()對應的 動畫類型是不一樣的,v4包下的是**Animation**,而app包下的是**Animator**;
**Animation一般動畫**就是我們前面學的**幀動畫和補間動畫**!**Animator**則是本節要講的**屬性動畫**!
關于屬性動畫,大牛郭大叔已經寫了三篇非常好的總結文,寫得非常贊,就沒必要重復造輪子了, 不過這里還是過一遍,大部分內容參考的下面三篇文章:
[Android屬性動畫完全解析(上),初識屬性動畫的基本用法](http://blog.csdn.net/guolin_blog/article/details/43536355)
[Android屬性動畫完全解析(中),ValueAnimator和ObjectAnimator的高級用法](http://blog.csdn.net/guolin_blog/article/details/43816093)
[Android屬性動畫完全解析(下),Interpolator和ViewPropertyAnimator的用法](http://blog.csdn.net/guolin_blog/article/details/44171115)
寫的非常好,或者說你可以直接跳過本文去看上面的三篇文章~
當然,你愿意看我叨叨逼的話,也很歡迎,好了,開始本節內容吧~
## 1.屬性動畫概念叨叨逼
不BB,直接上圖,就是這么暴力~

## 2.ValueAnimator簡單使用
**使用流程**:
* 1.調用ValueAnimator的**ofInt**(),**ofFloat**()或**ofObject**()靜態方法創建ValueAnimator實例
* 2.調用實例的setXxx方法設置動畫持續時間,插值方式,重復次數等
* 3.調用實例的**addUpdateListener**添加**AnimatorUpdateListener**監聽器,在該監聽器中 可以獲得ValueAnimator計算出來的值,你可以值應用到指定對象上~
* 4.調用實例的**start()**方法開啟動畫! 另外我們可以看到ofInt和ofFloat都有個這樣的參數:float/int... values代表可以多個值!
**使用示例**:

**代碼實現**:
布局文件:**activity_main.xml**,非常簡單,四個按鈕,一個ImageView
```
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ly_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="動畫1" />
<Button
android:id="@+id/btn_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="動畫2" />
<Button
android:id="@+id/btn_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="動畫3" />
<Button
android:id="@+id/btn_four"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="動畫4" />
<ImageView
android:id="@+id/img_babi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@mipmap/img_babi" />
</LinearLayout>
```
接著到**MainActivity.java**, 首先需要一個修改View位置的方法,這里調用**moveView**()設置左邊和上邊的起始坐標以及寬高!
接著定義了四個動畫,分別是:直線移動,縮放,旋轉加透明,以及圓形旋轉!
然后通過按鈕觸發對應的動畫~
```
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_one;
private Button btn_two;
private Button btn_three;
private Button btn_four;
private LinearLayout ly_root;
private ImageView img_babi;
private int width;
private int height;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
ly_root = (LinearLayout) findViewById(R.id.ly_root);
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
btn_three = (Button) findViewById(R.id.btn_three);
btn_four = (Button) findViewById(R.id.btn_four);
img_babi = (ImageView) findViewById(R.id.img_babi);
btn_one.setOnClickListener(this);
btn_two.setOnClickListener(this);
btn_three.setOnClickListener(this);
btn_four.setOnClickListener(this);
img_babi.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_one:
lineAnimator();
break;
case R.id.btn_two:
scaleAnimator();
break;
case R.id.btn_three:
raAnimator();
break;
case R.id.btn_four:
circleAnimator();
break;
case R.id.img_babi:
Toast.makeText(MainActivity.this, "不愧是coder-pig~", Toast.LENGTH_SHORT).show();
break;
}
}
//定義一個修改ImageView位置的方法
private void moveView(View view, int rawX, int rawY) {
int left = rawX - img_babi.getWidth() / 2;
int top = rawY - img_babi.getHeight();
int width = left + view.getWidth();
int height = top + view.getHeight();
view.layout(left, top, width, height);
}
//定義屬性動畫的方法:
//按軌跡方程來運動
private void lineAnimator() {
width = ly_root.getWidth();
height = ly_root.getHeight();
ValueAnimator xValue = ValueAnimator.ofInt(height,0,height / 4,height / 2,height / 4 * 3 ,height);
xValue.setDuration(3000L);
xValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 軌跡方程 x = width / 2
int y = (Integer) animation.getAnimatedValue();
int x = width / 2;
moveView(img_babi, x, y);
}
});
xValue.setInterpolator(new LinearInterpolator());
xValue.start();
}
//縮放效果
private void scaleAnimator(){
//這里故意用兩個是想讓大家體會下組合動畫怎么用而已~
final float scale = 0.5f;
AnimatorSet scaleSet = new AnimatorSet();
ValueAnimator valueAnimatorSmall = ValueAnimator.ofFloat(1.0f, scale);
valueAnimatorSmall.setDuration(500);
ValueAnimator valueAnimatorLarge = ValueAnimator.ofFloat(scale, 1.0f);
valueAnimatorLarge.setDuration(500);
valueAnimatorSmall.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
img_babi.setScaleX(scale);
img_babi.setScaleY(scale);
}
});
valueAnimatorLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
img_babi.setScaleX(scale);
img_babi.setScaleY(scale);
}
});
scaleSet.play(valueAnimatorLarge).after(valueAnimatorSmall);
scaleSet.start();
//其實可以一個就搞定的
// ValueAnimator vValue = ValueAnimator.ofFloat(1.0f, 0.6f, 1.2f, 1.0f, 0.6f, 1.2f, 1.0f);
// vValue.setDuration(1000L);
// vValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
// @Override
// public void onAnimationUpdate(ValueAnimator animation) {
// float scale = (Float) animation.getAnimatedValue();
// img_babi.setScaleX(scale);
// img_babi.setScaleY(scale);
// }
// });
// vValue.setInterpolator(new LinearInterpolator());
// vValue.start();
}
//旋轉的同時透明度變化
private void raAnimator(){
ValueAnimator rValue = ValueAnimator.ofInt(0, 360);
rValue.setDuration(1000L);
rValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int rotateValue = (Integer) animation.getAnimatedValue();
img_babi.setRotation(rotateValue);
float fractionValue = animation.getAnimatedFraction();
img_babi.setAlpha(fractionValue);
}
});
rValue.setInterpolator(new DecelerateInterpolator());
rValue.start();
}
//圓形旋轉
protected void circleAnimator() {
width = ly_root.getWidth();
height = ly_root.getHeight();
final int R = width / 4;
ValueAnimator tValue = ValueAnimator.ofFloat(0,
(float) (2.0f * Math.PI));
tValue.setDuration(1000);
tValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 圓的參數方程 x = R * sin(t) y = R * cos(t)
float t = (Float) animation.getAnimatedValue();
int x = (int) (R * Math.sin(t) + width / 2);
int y = (int) (R * Math.cos(t) + height / 2);
moveView(img_babi, x, y);
}
});
tValue.setInterpolator(new DecelerateInterpolator());
tValue.start();
}
}
```
好的,使用的流程非常簡單,先創建ValueAnimator對象,調用ValueAnimator.ofInt/ofFloat 獲得,然后設置動畫持續時間,**addUpdateListener**添加**AnimatorUpdateListener**事件監聽, 然后使用參數**animation**的**getAnimatedValue**()獲得當前的值,然后我們可以拿著這個值 來修改View的一些屬性,從而形成所謂的動畫效果,接著設置setInterpolator動畫渲染模式, 最后調用start()開始動畫的播放~
臥槽,直線方程,圓的參數方程,我都開始方了,這不是高數的東西么, 掛科學渣連三角函數都忘了...
例子參考自github:[MoveViewValueAnimator](https://github.com/nuptboyzhb/MoveViewValueAnimator)
## 3.ObjectAnimator簡單使用
比起ValueAnimator,ObjectAnimator顯得更為易用,通過該類我們可以**直接** **對任意對象的任意屬性進行動畫操作**!沒錯,是任意對象,而不單單只是View對象, 不斷地對對象中的某個屬性值進行賦值,然后根據對象屬性值的改變再來決定如何展現 出來!比如為TextView設置如下動畫: **ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f);**
這里就是不斷改變alpha的值,從1f - 0f,然后對象根據屬性值的變化來刷新界面顯示,從而 展現出淡入淡出的效果,而在TextView類中并沒有alpha這個屬性,ObjectAnimator內部機制是: **尋找傳輸的屬性名對應的get和set方法~,而非找這個屬性值!** 不信的話你可以到TextView的源碼里找找是否有alpha這個屬性! 好的,下面我們利用ObjectAnimator來實現四種補間動畫的效果吧~
**運行效果圖**:

**代碼實現**:
布局直接用的上面那個布局,加了個按鈕,把ImageView換成了TextView,這里就不貼代碼了, 直接上**MainActivity.java**部分的代碼,其實都是大同小異的~
```
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_one;
private Button btn_two;
private Button btn_three;
private Button btn_four;
private Button btn_five;
private LinearLayout ly_root;
private TextView tv_pig;
private int height;
private ObjectAnimator animator1;
private ObjectAnimator animator2;
private ObjectAnimator animator3;
private ObjectAnimator animator4;
private AnimatorSet animSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
initAnimator();
}
private void bindViews() {
ly_root = (LinearLayout) findViewById(R.id.ly_root);
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
btn_three = (Button) findViewById(R.id.btn_three);
btn_four = (Button) findViewById(R.id.btn_four);
btn_five = (Button) findViewById(R.id.btn_five);
tv_pig = (TextView) findViewById(R.id.tv_pig);
height = ly_root.getHeight();
btn_one.setOnClickListener(this);
btn_two.setOnClickListener(this);
btn_three.setOnClickListener(this);
btn_four.setOnClickListener(this);
btn_five.setOnClickListener(this);
tv_pig.setOnClickListener(this);
}
//初始化動畫
private void initAnimator() {
animator1 = ObjectAnimator.ofFloat(tv_pig, "alpha", 1f, 0f, 1f, 0f, 1f);
animator2 = ObjectAnimator.ofFloat(tv_pig, "rotation", 0f, 360f, 0f);
animator3 = ObjectAnimator.ofFloat(tv_pig, "scaleX", 2f, 4f, 1f, 0.5f, 1f);
animator4 = ObjectAnimator.ofFloat(tv_pig, "translationY", height / 8, -100, height / 2);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_one:
animator1.setDuration(3000l);
animator1.start();
break;
case R.id.btn_two:
animator2.setDuration(3000l);
animator2.start();
break;
case R.id.btn_three:
animator3.setDuration(3000l);
animator3.start();
break;
case R.id.btn_four:
animator4.setDuration(3000l);
animator4.start();
break;
case R.id.btn_five:
//將前面的動畫集合到一起~
animSet = new AnimatorSet();
animSet.play(animator4).with(animator3).with(animator2).after(animator1);
animSet.setDuration(5000l);
animSet.start();
break;
case R.id.tv_pig:
Toast.makeText(MainActivity.this, "不愧是coder-pig~", Toast.LENGTH_SHORT).show();
break;
}
}
}
```
用法也非常簡單,上面涉及到的組合動畫我們下面講~
## 4.組合動畫與AnimatorListener
從上面兩個例子中我們都體驗了一把組合動畫,用到了**AnimatorSet**這個類!
我們調用的play()方法,然后傳入第一個開始執行的動畫,此時他會返回一個Builder類給我們:

接下來我們可以調用Builder給我們提供的四個方法,來組合其他的動畫:
* **after**(Animator anim) 將現有動畫插入到傳入的動畫之后執行
* **after**(long delay) 將現有動畫延遲指定毫秒后執行
* **before**(Animator anim) 將現有動畫插入到傳入的動畫之前執行
* **with**(Animator anim) 將現有動畫和傳入的動畫同時執行
嗯,很簡單,接下來要說下動畫事件的監聽,上面我們ValueAnimator的監聽器是 **AnimatorUpdateListener**,當值狀態發生改變時候會回調**onAnimationUpdate**方法!
除了這種事件外還有:動畫進行狀態的監聽~ **AnimatorListener**,我們可以調用**addListener**方法 添加監聽器,然后重寫下面四個回調方法:
* **onAnimationStart()**:動畫開始
* **onAnimationRepeat()**:動畫重復執行
* **onAnimationEnd()**:動畫結束
* **onAnimationCancel()**:動畫取消
沒錯,加入你真的用AnimatorListener的話,四個方法你都要重寫,當然和前面的手勢那一節一樣, Android已經給我們提供好一個適配器類:**AnimatorListenerAdapter**,該類中已經把每個接口 方法都實現好了,所以我們這里只寫一個回調方法也可以額!
## 5.使用XML來編寫動畫
使用XML來編寫動畫,畫的時間可能比Java代碼長一點,但是重用起來就輕松很多! 對應的XML標簽分別為:<**animator**><**objectAnimator**><**set**> 相關的屬性解釋如下:
* **android:ordering**:指定動畫的播放順序:sequentially(順序執行),together(同時執行)
* **android:duration**:動畫的持續時間
* **android:propertyName**="x":這里的x,還記得上面的"alpha"嗎?加載動畫的那個對象里需要 定義getx和setx的方法,objectAnimator就是通過這里來修改對象里的值的!
* **android:valueFrom**="1" :動畫起始的初始值
* **android:valueTo**="0" :動畫結束的最終值
* **android:valueType**="floatType":變化值的數據類型
**使用例子如下**:
①**從0到100平滑過渡的動畫**:
```
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="100"
android:valueType="intType"/>
```
②**將一個視圖的alpha屬性從1變成0**:
```
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="alpha"/>
```
③**set動畫使用演示**:
```
<set android:ordering="sequentially" >
<set>
<objectAnimator
android:duration="500"
android:propertyName="x"
android:valueTo="400"
android:valueType="intType" />
<objectAnimator
android:duration="500"
android:propertyName="y"
android:valueTo="300"
android:valueType="intType" />
</set>
<objectAnimator
android:duration="500"
android:propertyName="alpha"
android:valueTo="1f" />
</set>
```
**加載我們的動畫文件**:
```
AnimatorSet set = (AnimatorSet)AnimatorInflater.loadAnimator(mContext,
R.animator.property_animator);
animator.setTarget(view);
animator.start();
```
## 6.本節示例代碼下載:
[AnimatorDemo1.zip](http://static.runoob.com/download/AnimatorDemo1.zip)
[AnimatorDemo2.zip](http://static.runoob.com/download/AnimatorDemo2.zip)
## 本節小結:
> 好的,本節給大家捋了一捋安卓中屬性動畫的基本用法,不知道你get了沒,內容還是比較簡單 的,而且例子比較有趣,相信大家會喜歡,嗯,就說這么多,謝謝~
感謝**郭神**的文章~
> 
- 1.0 Android基礎入門教程
- 1.0.1 2015年最新Android基礎入門教程目錄
- 1.1 背景相關與系統架構分析
- 1.2 開發環境搭建
- 1.2.1 使用Eclipse + ADT + SDK開發Android APP
- 1.2.2 使用Android Studio開發Android APP
- 1.3 SDK更新不了問題解決
- 1.4 Genymotion模擬器安裝
- 1.5.1 Git使用教程之本地倉庫的基本操作
- 1.5.2 Git之使用GitHub搭建遠程倉庫
- 1.6 .9(九妹)圖片怎么玩
- 1.7 界面原型設計
- 1.8 工程相關解析(各種文件,資源訪問)
- 1.9 Android程序簽名打包
- 1.11 反編譯APK獲取代碼&資源
- 2.1 View與ViewGroup的概念
- 2.2.1 LinearLayout(線性布局)
- 2.2.2 RelativeLayout(相對布局)
- 2.2.3 TableLayout(表格布局)
- 2.2.4 FrameLayout(幀布局)
- 2.2.5 GridLayout(網格布局)
- 2.2.6 AbsoluteLayout(絕對布局)
- 2.3.1 TextView(文本框)詳解
- 2.3.2 EditText(輸入框)詳解
- 2.3.3 Button(按鈕)與ImageButton(圖像按鈕)
- 2.3.4 ImageView(圖像視圖)
- 2.3.5.RadioButton(單選按鈕)&Checkbox(復選框)
- 2.3.6 開關按鈕ToggleButton和開關Switch
- 2.3.7 ProgressBar(進度條)
- 2.3.8 SeekBar(拖動條)
- 2.3.9 RatingBar(星級評分條)
- 2.4.1 ScrollView(滾動條)
- 2.4.2 Date & Time組件(上)
- 2.4.3 Date & Time組件(下)
- 2.4.4 Adapter基礎講解
- 2.4.5 ListView簡單實用
- 2.4.6 BaseAdapter優化
- 2.4.7ListView的焦點問題
- 2.4.8 ListView之checkbox錯位問題解決
- 2.4.9 ListView的數據更新問題
- 2.5.0 構建一個可復用的自定義BaseAdapter
- 2.5.1 ListView Item多布局的實現
- 2.5.2 GridView(網格視圖)的基本使用
- 2.5.3 Spinner(列表選項框)的基本使用
- 2.5.4 AutoCompleteTextView(自動完成文本框)的基本使用
- 2.5.5 ExpandableListView(可折疊列表)的基本使用
- 2.5.6 ViewFlipper(翻轉視圖)的基本使用
- 2.5.7 Toast(吐司)的基本使用
- 2.5.8 Notification(狀態欄通知)詳解
- 2.5.9 AlertDialog(對話框)詳解
- 2.6.0 其他幾種常用對話框基本使用
- 2.6.1 PopupWindow(懸浮框)的基本使用
- 2.6.2 菜單(Menu)
- 2.6.3 ViewPager的簡單使用
- 2.6.4 DrawerLayout(官方側滑菜單)的簡單使用
- 3.1.1 基于監聽的事件處理機制
- 3.2 基于回調的事件處理機制
- 3.3 Handler消息傳遞機制淺析
- 3.4 TouchListener PK OnTouchEvent + 多點觸碰
- 3.5 監聽EditText的內容變化
- 3.6 響應系統設置的事件(Configuration類)
- 3.7 AnsyncTask異步任務
- 3.8 Gestures(手勢)
- 4.1.1 Activity初學乍練
- 4.1.2 Activity初窺門徑
- 4.1.3 Activity登堂入室
- 4.2.1 Service初涉
- 4.2.2 Service進階
- 4.2.3 Service精通
- 4.3.1 BroadcastReceiver牛刀小試
- 4.3.2 BroadcastReceiver庖丁解牛
- 4.4.2 ContentProvider再探——Document Provider
- 4.5.1 Intent的基本使用
- 4.5.2 Intent之復雜數據的傳遞
- 5.1 Fragment基本概述
- 5.2.1 Fragment實例精講——底部導航欄的實現(方法1)
- 5.2.2 Fragment實例精講——底部導航欄的實現(方法2)
- 5.2.3 Fragment實例精講——底部導航欄的實現(方法3)
- 5.2.4 Fragment實例精講——底部導航欄+ViewPager滑動切換頁面
- 5.2.5 Fragment實例精講——新聞(購物)類App列表Fragment的簡單實現
- 6.1 數據存儲與訪問之——文件存儲讀寫
- 6.2 數據存儲與訪問之——SharedPreferences保存用戶偏好參數
- 6.3.1 數據存儲與訪問之——初見SQLite數據庫
- 6.3.2 數據存儲與訪問之——又見SQLite數據庫
- 7.1.1 Android網絡編程要學的東西與Http協議學習
- 7.1.2 Android Http請求頭與響應頭的學習
- 7.1.3 Android HTTP請求方式:HttpURLConnection
- 7.1.4 Android HTTP請求方式:HttpClient
- 7.2.1 Android XML數據解析
- 7.2.2 Android JSON數據解析
- 7.3.1 Android 文件上傳
- 7.3.2 Android 文件下載(1)
- 7.3.3 Android 文件下載(2)
- 7.4 Android 調用 WebService
- 7.5.1 WebView(網頁視圖)基本用法
- 7.5.2 WebView和JavaScrip交互基礎
- 7.5.3 Android 4.4后WebView的一些注意事項
- 7.5.4 WebView文件下載
- 7.5.5 WebView緩存問題
- 7.5.6 WebView處理網頁返回的錯誤碼信息
- 7.6.1 Socket學習網絡基礎準備
- 7.6.2 基于TCP協議的Socket通信(1)
- 7.6.3 基于TCP協議的Socket通信(2)
- 7.6.4 基于UDP協議的Socket通信
- 8.1.1 Android中的13種Drawable小結 Part 1
- 8.1.2 Android中的13種Drawable小結 Part 2
- 8.1.3 Android中的13種Drawable小結 Part 3
- 8.2.1 Bitmap(位圖)全解析 Part 1
- 8.2.2 Bitmap引起的OOM問題
- 8.3.1 三個繪圖工具類詳解
- 8.3.2 繪圖類實戰示例
- 8.3.3 Paint API之—— MaskFilter(面具)
- 8.3.4 Paint API之—— Xfermode與PorterDuff詳解(一)
- 8.3.5 Paint API之—— Xfermode與PorterDuff詳解(二)
- 8.3.6 Paint API之—— Xfermode與PorterDuff詳解(三)
- 8.3.7 Paint API之—— Xfermode與PorterDuff詳解(四)
- 8.3.8 Paint API之—— Xfermode與PorterDuff詳解(五)
- 8.3.9 Paint API之—— ColorFilter(顏色過濾器)(1/3)
- 8.3.10 Paint API之—— ColorFilter(顏色過濾器)(2-3)
- 8.3.11 Paint API之—— ColorFilter(顏色過濾器)(3-3)
- 8.3.12 Paint API之—— PathEffect(路徑效果)
- 8.3.13 Paint API之—— Shader(圖像渲染)
- 8.3.14 Paint幾個枚舉/常量值以及ShadowLayer陰影效果
- 8.3.15 Paint API之——Typeface(字型)
- 8.3.16 Canvas API詳解(Part 1)
- 8.3.17 Canvas API詳解(Part 2)剪切方法合集
- 8.3.18 Canvas API詳解(Part 3)Matrix和drawBitmapMash
- 8.4.1 Android動畫合集之幀動畫
- 8.4.2 Android動畫合集之補間動畫
- 8.4.3 Android動畫合集之屬性動畫-初見
- 8.4.4 Android動畫合集之屬性動畫-又見
- 9.1 使用SoundPool播放音效(Duang~)
- 9.2 MediaPlayer播放音頻與視頻
- 9.3 使用Camera拍照
- 9.4 使用MediaRecord錄音
- 10.1 TelephonyManager(電話管理器)
- 10.2 SmsManager(短信管理器)
- 10.3 AudioManager(音頻管理器)
- 10.4 Vibrator(振動器)
- 10.5 AlarmManager(鬧鐘服務)
- 10.6 PowerManager(電源服務)
- 10.7 WindowManager(窗口管理服務)
- 10.8 LayoutInflater(布局服務)
- 10.9 WallpaperManager(壁紙管理器)
- 10.10 傳感器專題(1)——相關介紹
- 10.11 傳感器專題(2)——方向傳感器
- 10.12 傳感器專題(3)——加速度/陀螺儀傳感器
- 10.12 傳感器專題(4)——其他傳感器了解
- 10.14 Android GPS初涉
- 11.0《2015最新Android基礎入門教程》完結散花~