本章介紹Canvas組件,用它來生成簡單的二維(2D)圖形,目標是創建一個PaintPot(油漆桶)應用,讓用戶在手機屏幕上繪制圖畫,并讓用戶用手機給自己拍照,然后在自己的照片上繪圖。回顧歷史,早在20世紀70年代,PaintPot是最早運行在個人電腦上的應用之一,目的是為了證明個人電腦的潛力。那時候,開發這樣一款簡單的繪圖應用是一項極其復雜的工作,而且繪圖效果也略顯粗糙。但現在,使用App Inventor,任何人都可以快速地創建一個有趣的繪圖應用,這也是創建2D游戲的起點。
如圖2-1,油漆桶應用將實現下列目標:
* 用手指點取顏色并繪圖;
* 用手指在手機屏幕上畫線;
* 用手指觸碰手機屏幕畫圓點;
* 點擊按鈕來擦凈屏幕;
* 點擊按鈕來改變繪制圓點的大小;
* 用相機拍攝照片,并在照片上畫圖。


**圖 2-1 油漆桶應用**
## **學習內容**
本章涵蓋了以下內容:
* 使用Canvas組件來繪制圖畫;
* 處理屏幕上的觸摸及拖拽事件;
* 使用arrangement組件來控制屏幕的外觀;
* 使用帶有參數的事件處理程序;
* 定義變量,來保存某些狀態,如用戶繪制的圓點的大小。
## **準備開始**
首先檢查測試用的Android設備是否已經為使用App Inventor做好了準備:
* Android設備中已經安裝了“AI伴侶”;
* 手機的WiFi連接已經打開;
再訪問[App Inventor](http://ai2.appinventor.mit.edu/)網站。新建項目“PaintPot”,點擊“Connect->AICompanion”,并按照提示操作,連接測試設備。
在正式開始之前,在組件設計器右側的“屬性”面板中,將“Screen1”的“Title”屬性修改為“油漆桶”。在測試設備上可以立即看到這一改變:應用的標題欄將顯示“油漆桶”。
這樣做是否會混淆了項目名稱與屏幕標題呢(在英文版書中,將Title改為“PaintPot”,與項目同名,因此才有此疑問,對中文讀者來說不存在這個疑問。——譯者注)?別擔心!在App Inventor中有三個非常重要名稱:
* 項目名稱:同時也是應用發布時所使用的名稱。提示:想修改項目名稱,可以點擊Project->Save project as,可以將原有項目賦予新的名稱,同時原有項目依然得以保留;
* 組件名稱:一般的組件名稱都可以修改,但Screen1例外,在當前版本中不能修改它的名稱;
* 屏幕標題:出現在設備的標題欄中,是Screen組件的Title屬性,默認值是Screen1,如第一章HelloPurr中所見,可以隨意修改它,如我們剛才將其改為“油漆桶”。
## **設計組件**
創建“油漆桶”應用需要以下組件:
* 三個Button組件:用來選擇畫筆顏色:紅、藍或綠,放在HorizontalArrangement組件中;
* 一個Button組件用來充當橡皮;
* 另外兩個Button組件用來改變畫筆的大小;
* 一個Canvas組件,充當畫布。Canvas具有BackgroundImage屬性,我們將其設置為第一章HelloPurr中的kitty.png,稍后還可以將背景圖片設置為用戶拍攝的照片。
### **創建顏色按鈕**
首先按照以下提示創建三個顏色按鈕:
1\. 拖一個Button組件到預覽窗口,設置其Text屬性為“紅”,BackgroundColor屬性設為紅色;
2\. 在組件列表中選中Button1(可能已經被選中),點擊Rename按鈕將組件名稱改為RedButton。注意組件名稱中不允許有空格,因此通常將組件名稱中每個單詞的首字母大寫。
3\. 同樣,創建另外兩個按鈕,分別命名為BlueButton和GreenButton,將它們垂直地放在RedButton下方。對照圖2-2,檢查一下你的操作結果。

**圖 2-2 創建了3個按鈕的預覽窗口**
注意:在項目中,建議為組建起一個有意義的名稱,而不是像第一章那樣采用默認名稱。有意義的名稱增加了程序的可讀性,尤其是在切換到塊編輯器時,將有助于區分不同的組件。本書中,采用慣用的駱駝命名法(如RedButton),即多單詞無空格的首字母大寫命名方式。
>  測試:如果你還沒有點擊“Connect”來連接測試設備,那么做好連接,然后檢查一下應用在設備(如果已經連接)上的表現。
### **使用Arrangement組件改善布局**
現在三個按鈕排成一列縱隊,我們希望它們能排成一行,如圖2-3所示,使用HorizontalArrangement組件來實現組件的水平排列:
1\. 在組件面板的Layout類中拖出HorizontalArrangement組件,放在按鈕下方;
2\. 在屬性面板中,設置HorizontalArrangement的width屬性為“Fill Parent”(充滿父容器),以便在水平方向上占滿整個屏幕;
3\. 將三個按鈕移動到HorizontalArrangement中。注意,當你拖拽按鈕時,會看到一條藍色豎線,提示按鈕將會被放置在什么地方。

**圖 2-3 在水平布局組件內的三個按鈕**
此時查看組件列表,你會發現三個按鈕縮進排列在HorizontalArrangement項下,以顯示它們現在是次一級的組件。同時注意到所有組件都縮進排在Screen1項下。
>  測試:在測試設備的屏幕上,你會看到三個按鈕排列成一行,盡管看起來與預覽窗口中略有不同。如,在預覽窗口中可見的HorizontalArrangement周圍的輪廓線,在測試設備上則不可見。
通常采用布局組件來創建簡單的垂直、水平或表格布局,也可以通過逐級插入(或嵌套)布局組件來創建更加復雜的布局。
### **添加Canvas(畫布)**
Canvas像一塊畫布,用戶可以在上面繪畫(畫圓、畫等)。添加一個Canvas,并用第一章中的kitty.png作它的背景圖片(設置BackgroundImage屬性),具體步驟如下:
1\. 打開組件面板中的Drawing and Amination(繪畫與動畫)類,將Canvas組件拖到預覽窗口中,改名為DrawingCanvas,Width設為“Fill parent”,Height設為300pixels;
2\. 如果你已經完成了第一章的課程,那么文件kitty.png已經下載;如果沒有,請在這里下載kitty.png。
3\. 將DrawingCanvas的BackgroundImage設置為kitty.png:在設計器的屬性面板中,BackgroundImage的默認值為None,點擊None及Upload File來添加kitty.png文件;
4\. 將DrawingCanvas的PaintColor屬性設置為red,以便當用戶剛啟動應用但尚未點擊顏色按鈕時,畫筆為紅色。對照圖2-4檢查一下你的操作。

**圖 2-4 背景圖片設為kitty.png的DrawingCanvas組件**
### **設置底部按鈕及照相機組件**
1\. 從組件面板中拖出第二個HorizontalArrangement,放在canvas下方,再拖兩個Button并置于屏幕底部的HorizontalArrangement中;將第一個按鈕改名為TakePictureButton,Text屬性設為“拍照”;第二個按鈕改名為WipeButton,Text屬性設為“清除”;
2\. 再拖兩個Button組件到HorizontalArrangement中,放在“清除”按鈕后面;
3\. 兩個Button分別命名為BigButton、SmallButton,Text屬性分別設為“大圓”、“小圓”;
4\. 從組件的Media類中拖出一個Camera組件放在預覽窗口中,它將落在非可視組件區。
到此為止,應用外觀已經設置完成,如圖2-5所示。

**圖 2-5 油漆桶應用的完整用戶界面**
>  測試:在設備上檢查一下應用,貓的圖片是否在頂部的一行按鈕的下方?底部的按鈕是否正常顯示?
## **為組建添加行為**
下一步將定義組件的行為。編寫一個繪畫程序的難度似乎是難以想象的,但無疑App Inventor已經承擔了大部分繁重的工作:這里有易于使用的塊語言,不但可以處理用戶的觸摸及拖拽事件,也可以實現繪畫及拍照功能。
Canvas組件具有Touched及Dragged事件,你可以針對DrawingCanvas.Touched(觸碰)事件編程,并調用DrawingCanvas.DrawCircle(畫圓)程序;也可以對DrawingCanvas.Dragged(拖拽)事件編程來調用DrawingCanvas.DrawLine(畫線)程序。然后對按鈕編程,來設置DrawingCanvas.PaintColor(畫筆顏色)屬性、清除DrawingCanvas,以及將DrawingCanvas的背景圖片修改為照相機拍攝的圖片。
### **添加觸摸事件,繪制一個圓點**
首先設置觸碰行為:當用戶觸碰DrawingCanvas時,在接觸點繪制一個圓點:
1\. 在塊編輯器中,打開DrawingCanvas抽屜拖出DrawingCanvas.Touched塊,該塊有三個參數x、y及touchedSprite,如圖2-6所示。這些參數提供了接觸點的位置信息;

**圖 2-6 帶有接觸點位置信息的Toughed事件**
>  提示:在第一章HelloPurr應用中已經熟悉了Button.Click事件,但對Canvas事件還很陌生。Button.Click事件的發生很簡單,不附帶任何其他信息;但有些事件則不然,它們附帶了與事件有關的“參數”信息。DrawingCanvas.Touched事件中的x、y代表接觸點在DrawingCanvas中的坐標,而touchedSprite代表接觸點所碰到的DrawingCanvas中的對象(在App Inventor中稱作sprite—精靈),但在第三章之前我們不會用到它。我們將利用接觸點的xy坐標來繪制圓點。
2\. 從DrawingCanvas抽屜中拖出DrawingCanvas.DrawCircle命令塊,放在DrawingCanvas.Touched事件處理程序中,如圖2-7所示;

**圖 2-7 用戶觸摸畫布時,應用繪制一個圓點**
在DrawingCanvas.DrawCircle塊的右側有三個插槽,需要填入三個參數:x、y、r。其中x、y用于指定繪制圓形的位置,r用于指定圓的半徑。在屏幕左下角帶感嘆號的黃色警告顯示數字“1”,表示需要填滿這些插槽。從圖中看到,有兩組xy,這里要區分清楚:DrawingCanvas.Touched事件中的xy表示接觸點位置(已知);而DrawingCanvas.DrawCircle命令塊的xy插槽,用于設定繪制圓形的位置(待定)。我們恰好要在用戶的接觸點繪制圓形,因此DrawingCanvas.Touched事件中的xy值,可以作為DrawingCanvas.DrawCircle的x、y參數,插入到插槽中。
>  提示:可以從“when”塊中提取事件的參數值,將鼠標懸停在參數上,將呼出“get”及“set”塊。可以將“get x”塊拖出并插到x插槽中,作為DrawCircle命令的x值。如圖2-8所示。

**圖 2-8 讀取事件參數:從DrawingCanvas.Touched事件中拖出“get x”塊**
3\. 將鼠標懸停在x、y參數上可以喚出“get”塊,將“get”塊插入到DrawingCanvas.DrawCircle的插槽中,如圖2-8、2-9所示;

**圖 2-9 已經設定了圓的位置(x,y),尚未指定圓的大小**
4\. 下面來設定圓的半徑r。長度的單位是pixel(像素),是屏幕上能夠繪制的最小的點。設r = 5:點擊屏幕的空白區域,輸入5然后回車(自動創建數字塊“5”)并將其插入插槽r中。再看屏幕左下角的黃色三角形,數字由1變為0,因為所有插槽都被填滿了。圖2-10顯示了DrawingCanvas.Touched事件處理程序最終的樣子。

**圖 2-10 當用戶觸碰DrawingCanvas時,將在(x,y)點繪制一個半徑為5的圓形**
>  提示:在塊編輯器中輸入5然后回車,這種操作叫做輸入塊(typeblocking)。塊編輯器會根據你輸入的字符,顯示與該字符相匹配的一系列塊;如果輸入的是數字,那么將創建一個數字塊。
>
>  測試:看看測試設備上都有什么。觸碰 DrawingCanvas,手指碰過的地方會留下一個圓點。如果在設計器中將DrawingCanvas.PaintColor屬性設置為紅色,那么圓點也是紅色(否則應該是默認的黑色)。
### **添加畫線的拖拽事件**
下面添加拖拽事件處理程序,先看一下觸碰(Toughed)事件與拖拽(Dragged)事件的區別:
* 觸碰事件:手指在DrawingCanvas(畫布)上放下再抬起,其間手指沒有移動。
* 拖拽事件:手指在DrawingCanvas(畫布)上放下,手指與屏幕保持接觸并移動。
在繪圖程序中,手指在屏幕上拖動,沿著手指移動的路徑,將繪制出一條巨大的曲線,因為這條曲線實際上由數百個微小的線段構成:手指每次微小的移動,都將繪制一個微小的線段。
1\. 從DrawingCanvas抽屜中拖出DrawingCanvas.Dragged事件處理程序塊,如圖2-11所示;DrawingCanvas.Dragged事件攜帶了以下參數:
* StartX、StartY:手指開始拖動時所在的位置(整個曲線的起點);
* currentX、currentY:手指的當前位置(微小線段的終點);
* prevX、prevY:手指的上一個位置(微小線段的起點);
* draggedSprite:布爾值,如果用戶直接拖動一個圖片,則其值為真。本章不會用到這個參數。

**圖 2-11 比起Toughed事件,Dragged事件攜帶了更多參數**
2\. 從DrawingCanvas抽屜中拖出DrawingCanvas.DrawLine塊,插入DrawingCanvas.Dragged塊中,如圖2-12所示。

**圖 2-12 添加畫線功能**
DrawingCanvas.DrawLine塊有四個參數,兩點確定一線:設(X1,Y1)為起點,(X2,Y2)為終點。你能確定每個參數中需要插入什么值嗎?記住,當手指在DrawingCanvas上拖動時,拖動事件將被調用很多次:在應用中,手指的每次移動都會繪制出一個微小線段,從(Prevx, prevy)到(currentX, currentY)。現在把它們填入DrawingCanvas.DrawLine塊。
3\. 拖出“get”塊來充當畫線的參數。將get prevX與get prevY分別插入到x1和y1插槽;而get currentX與get currentY插入到x2和y2插槽,如圖2-13所示。

**圖 2-13 用戶在屏幕上拖動手指,應用就在前一位置與當前位置之間畫一條微小線段**
>  測試:在設備上測試一下剛剛設定的行為:在屏幕上隨意拖動手指,畫出線段及曲線;觸碰屏幕畫出一個圓點。
### **添加按鈕事件處理程序**
應用已經實現了畫線功能,但現在只能畫紅線。下面添加顏色按鈕的事件處理程序,用戶可以改變畫筆的顏色;同樣設置清除按鈕WipeButton,以便用戶可以清除畫面并重新開始。
在塊編輯器中:
1\. 展開左側塊的(Blocks)列表;
2\. 打開RedButton抽屜,拖出RedButton.Click塊;
3\. 打開DrawingCanvas抽屜。拖出set DrawingCanvas.PaintColor塊(可能需要滾動塊的列表以便在抽屜里找到它),并把它放在RedButton.Click塊“do”的位置;
4\. 打開Colors抽屜,拖出紅色塊,將其插入set DrawingCanvas.PaintColor塊的插槽;
5\. 重復步驟2-4,設置藍色和綠色按鈕;
6\. 最后設置WipeButton按鈕。從WipeButton抽屜中拖出WipeButton.Click塊。再從DrawingCanvas抽屜里拖出DrawingCanvas.Clear塊,并將其放在WipeButton.Click塊中。確認所有塊顯示如圖2-14所示。

**圖 2-14 單擊顏色按鈕改變DrawingCanvas的畫筆顏色;單擊清除按鈕清空屏幕**
### **讓用戶拍照片**
App Inventor應用可以與Android設備的強大功能進行交互,包括相機功能。為了增加應用的趣味性,用戶可以將繪圖背景設置為他們用相機拍攝的照片。
1\. Camera組件有兩個關鍵的塊:Camera.TakePicture塊用來啟動設備上的拍照程序;拍照完成將觸發Camera.AfterPicture事件。在Camera.AfterPicture事件處理程序中,可以將剛剛拍攝的照片設置為DrawingCanvas.BackgroundImage。打開TakePictureButton抽屜并拖出TakePictureButton.Click事件處理程序;
2\. 從Camera1抽屜拖出Camera1.TakePicture放在TakePictureButton.Click事件處理程序中;
3\. 從Camera1的抽屜中拖出Camera1.AfterPicture事件處理程序;
4\. 從DrawingCanvas抽屜拖出set DrawingCanvas.BackgroundImage塊放在Camera1.AfterPicture事件處理程序中;
5\. Camera1.AfterPicture事件有一個名為image的參數,代表剛剛拍攝的照片,將從Camera1.AfterPicture塊中得到的get image塊插入DrawingCanvas.BackgroundImage塊。
所有的塊如圖2-15所示 。

**圖 2-15 拍完的照片被設置為DrawingCanvas的背景圖片**
>  測試:在設備上點擊“拍照”按鈕并拍攝照片,貓的圖片變成了你拍的照片。你可以在自己的照片上進行繪畫。(用Wolber教授的照片繪畫是學生們的一大樂事,如圖2-16。)(Wolber教授是本書的作者之一。)
### **改變畫筆大小**

**圖 2-16 帶有Wolber教授涂鴉照片的PaintPot應用**
在DrawingCanvas上畫圓點,其大小由DrawingCanvas.DrawCircle塊中參數r決定。改變r值可以改變圓點的大小。試試看將5改為10,然后在測試設備上查看結果。
另一個問題是,無論開發者如何設置參數r,用戶都只能用這個固定的尺寸。如何讓用戶來改變圓點的大小呢?為此我們來修改程序:當用戶點擊“大圓”按鈕時,圓點半徑設為8,當點擊“小圓”時半徑設為2。
我們要用不同的半徑畫圓,但應用怎么知道我們要用哪個值呢?必須通知應用我們選定的值,而應用必須以某種方式記住(或保存)這個值,這樣才能在需要的時候使用它。之前我們所使用的值,要么設定為屬性(如畫筆顏色),要么用固定的數字塊(如畫筆大小),現在應用需要記住一些屬性之外的、不是固定不變的東西,這就需要定義一個變量。變量是一個存儲單元,可以把它想象成一個容器,里面存儲著可變的數據,如畫筆的大小(有關變量的詳細信息,請參見App Inventor指南第16章)。
讓我們先來定義一個變量dotSize:
1\. 在塊編輯器中,從Variables(變量)抽屜中拖出一個initialize global name to塊。將“name”改為“dotSize”;
2\. 請注意,initialize global dotSize to塊有一個開放的插槽,可以在這里設定變量的初始值,或者說是應用啟動時的默認值(編程術語稱為“初始化變量”)。在本應用中,用數字塊2來初始化變量dotSize,(創建塊“2”的方法有兩種:在空白區直接輸入“2”然后回車;或從Math抽屜中拖出“0”塊,將0改為2。)將其插到initialize global dotSize to塊的插槽中,如圖2-17所示。

**圖 2-17 將dotSize變量的初始值設為2**
### **使用變量**
下一步,我們要修改DrawingCanvas.Touched事件處理程序,將其中DrawingCanvas.DrawCircle塊的參數r的固定值用變量dotSize來代替。(我們先將dotSize的初始值設定為“固定”的2,但稍后我們將改變dotSize的值,并同時改變畫筆的大小。)
1\. 從initialize global dotSize to塊中拖出一個get global dotSize塊,用它來提供變量的值;
2\. 轉到DrawingCanvas.Touched事件處理程序,將數字塊“5”拖出插槽并扔進垃圾桶,用get global dotSize塊來替換(見圖2-18)。當用戶觸摸到DrawingCanvas時,應用將根據dotSize的大小來確定圓點的半徑。

**圖 2-18 畫筆的大小取決于變量dotSize中保存的值**
### **修改變量值**
現在變量魔法登場,變量dotSize允許用戶選擇畫筆的大小,而事件處理程序也將以dotSize為半徑來畫圓。通過設計SmallButton.Click和BigButton.Click的事件處理程序來實現此功能:
1\. 從SmallButton抽屜中拖出SmallButton.Click事件處理程序;再從Variables抽屜中拖出一個“set”塊,下拉選擇global dotSize,并將其插入SmallButton.Click塊;最后,創建一個數字塊“2”,并將其插入set global dotSize塊。
2\. 創建另一個類似的BigButton.Click事件處理程序,設置畫筆大小為8。這兩個事件處理程序顯示在塊編輯器中,如圖2-19所示。

**圖 2-19 點擊SmallButton及BigButton按鈕改變畫筆大小,之后將以該尺寸繪制圖形**
>  提示: get/set global dotSize 之中的“global”(全局)指的是該變量適用于程序中所有的事件處理程序(全局)。與global相對的是“local”(局部)變量,適用于程序的特定部分;App Inventor 2中添加了此項功能,第12章首次使用。
>
>  測試:嘗試單擊“大圓”、“小圓”按鈕,然后在DrawingCanvas上觸碰,所繪圓點的大小是否不同?畫線呢?線沒有變化,因為只有DrawingCanvas.DrawCircle塊使用了變量dotSize。在此基礎上,考慮修改塊的設置,以使畫筆的大小,對畫線也同樣有效。注意:DrawingCanvas有一個“LineWidth(線寬)”的屬性。
## **油漆桶的完整應用**
圖2-20中顯示了完整的油漆桶應用。

**圖 2-20 油漆桶應用中塊的最終設置**
## **改進**
可以考慮做以下改進:
1\. 用戶界面中沒有顯示當前的狀態信息(如畫筆大小或顏色),只能通過畫圖來得知這些信息。修改應用,向用戶顯示當前的狀態信息;
2\. 讓用戶在TextBox組件內輸入畫筆的尺寸,這樣一來,除了2和8之外,他還可以將其更改為其他數值。有關TextBox組件的詳細信息,請參閱第4章。
## **小結**
本章涵蓋了如下內容:
* DrawingCanvas組件:用于在其中繪畫,也可以感知觸摸及拖動事件,可以利用這些事件來實現繪圖功能;
* 使用布局組件(HorizontalAarrangement),使多個組件的布局條理化,而不是摞在一起;
* 有些事件處理程序附帶了與事件有關的信息,例如Toughed事件中附帶了觸摸點的坐標,這些信息用參數來表示。在使用帶參數的事件處理程序時,App Inventor以塊的方式生成“get”及“set”項,來獲取這些參數的引用;
* 創建變量可以使用Variables抽屜中的initialize global name to塊,變量可以讓應用記住那些沒有被存儲成組件屬性的信息,如畫筆的大小;
* 對于定義的每一個變量,App Inventor提供了變量的讀寫方法:get global variable用來獲取變量的值(讀),而set global variable用來設置/修改變量的值(寫)。可以從變量初始化塊的變量名中拖出“get”或“set”塊。
本章介紹了DrawingCanvas組件如何應用于繪畫程序。也可以用它來編寫某些2D游戲中的動畫,更多信息請參見第5章“瓢蟲快跑”游戲,以及第17章中關于動畫的討論。
### **畫筆應用**
在譯者用過的最早的windows3.0中就有畫筆的應用,直到現在這個應用都是windows不可缺少的組成部分,雖然我們不常用它。

**圖 2.1 windows中的畫筆應用**
### **開發及測試**
如果無法訪問[App inventor](http://ai2.appinventor.mit.edu/)網站,可以嘗試譯者提供的[替代版本](http://www.17coding.net:8888/),或點擊頁面右上角的“開發體驗”按鈕。

**圖 2.2 用手機掃描下載并安裝"AI伴侶"**
### **駱駝命名法**
這是一個編程術語,指的是變量的命名規則:由于變量名中不允許出現空格,因此當需要用多個英文單詞為變量命名時,通過每個單詞的首字母大寫來區分不同的單詞,如本例中的紅色按鈕命名為RedButton,其中第一個單詞的首字母也可以小寫,即redButton。
### **中英文對照**
canvas:畫布
paint:油漆
pot:罐,容器
horizontal:水平的
arrangement:布置
background:背景
image:圖像
touch:觸摸
drag:拖拽
draw:繪畫
circle:圓
line:線
color:顏色
sprite:精靈
get:取得
set:設置
type:打字
block:塊
start:開始
current:現在
prev:前一個
button:按鈕
wipe:擦去
camera:相機
take picture:照相
after:在...之后
dot:點
size:尺寸
initialize:初始化
global:全局的
click:點擊
big:大的
small:小的
width:寬度
- 簡介
- 序言
- 前言
- 第 1 章 Hello 貓咪
- 第 2 章 油漆桶
- 第 3 章 打地鼠
- 第 4 章 開車不發短信
- 第 5 章 瓢蟲快跑
- 第 6 章 巴黎地圖旅游
- 第 7 章 安卓,我的車在哪?
- 第 8 章 總統測驗
- 第 9 章 木琴
- 第 10 章 出題及答題
- 第 11 章 廣播中心
- 第 12 章 遙控機器人
- 第 13 章 亞馬遜掌上書店
- 第 14 章 理解應用的結構
- 第 15 章 軟件工程與應用調試
- 第 16 章 應用中的存儲
- 第 17 章 創建動畫應用
- 第 18 章 程序中的決策:條件塊
- 第 19 章 數據列表編程
- 第 20 章 循環
- 第 21 章 定義過程
- 第 22 章 數據庫
- 第 23 章 傳感器
- 第 24 章 與Web API通信