牟曉東
這期我們用App Inventor制作一個(gè)繪圖板APP,用戶可以畫畫,有設(shè)置畫筆粗細(xì)和顏色,可以導(dǎo)入圖片和自己拍攝的照片作為背景,畫完后可以保存圖片。通過(guò)這個(gè)APP,我們可以掌握畫布組件、照相機(jī)組件的基本功能,了解RGB顏色的原理,理解觸摸和拖拽事件,并掌握借助計(jì)時(shí)器組件實(shí)現(xiàn)文件名唯一性的小技巧。
我們要去圖庫(kù)網(wǎng)站收集保存、拍照、文件夾、橡皮、鉛筆等圖標(biāo),新建項(xiàng)目,將圖標(biāo)上傳到素材中。
Screen1屏幕組件:在屏幕中放入垂直布局,在垂直布局中放入畫布組件和水平布局。
在水平布局中依次放入“圖像選擇組件(打開(kāi))、空白標(biāo)簽、按鈕(相機(jī))、空白標(biāo)簽、按鈕(保存)、空白標(biāo)簽、按鈕(橡皮)、按鈕(紅筆)、文本輸入框R、按鈕(綠筆)、文本輸入框G、按鈕(藍(lán)筆)、文本輸入框B、按鈕(OK)、標(biāo)簽(粗細(xì))、滑動(dòng)條(最大值50,最小值1)”。并為它們重命名。
放入兩個(gè)隱藏組件:照相機(jī)、計(jì)時(shí)器(圖1)。
各組件的詳細(xì)屬性如下表。
在屏幕設(shè)計(jì)中為了防止組件之間緊貼在一起,在兩個(gè)按鈕之間加入一個(gè)標(biāo)簽,標(biāo)簽的文本為空,這樣的標(biāo)簽就起到了空格的作用(圖2)。
完成組件設(shè)計(jì)后,先別急著邏輯設(shè)計(jì),最好先在手機(jī)中實(shí)測(cè)調(diào)試,并根據(jù)實(shí)際情況調(diào)整組件設(shè)計(jì)。
當(dāng)手指在畫布上輕觸會(huì)畫下一個(gè)實(shí)心圓點(diǎn)。用“當(dāng)畫布被觸碰”事件,用“畫圓”的方法實(shí)現(xiàn)此功能。
畫圓方法有4個(gè)參數(shù)槽,通過(guò)確定圓心的坐標(biāo)和圓的半徑,確定圓點(diǎn)的大小和位置,“啟用填充”只能連接邏輯值“真”或“假”,默認(rèn)為“真”表示實(shí)心圓(圖3)。
計(jì)算機(jī)用坐標(biāo)和像素單位來(lái)確定屏幕位置,在App Inventor中屏幕左上角的坐標(biāo)是(x=0,y=0),往右x值不斷增加,往下y值不斷增大。這與我們習(xí)慣的Scratch的坐標(biāo)原點(diǎn)位置不同(圖4、圖5)。
下面我們來(lái)實(shí)現(xiàn)手指拖動(dòng)畫線的功能,響應(yīng)“被拖動(dòng)”事件。畫布“被拖動(dòng)”事件處理器中可傳入7個(gè)參數(shù)。包括起點(diǎn)坐標(biāo)、前點(diǎn)坐標(biāo)、當(dāng)前坐標(biāo)和任意被拖拽的精靈。
起點(diǎn)坐標(biāo)和當(dāng)前坐標(biāo)好理解,連接這兩個(gè)點(diǎn)就能畫出一條長(zhǎng)直線。
前點(diǎn)坐標(biāo)是指上個(gè)采樣時(shí)間點(diǎn)手機(jī)采集到的手指觸摸畫布的位置,由于采樣間隔很短,連接前點(diǎn)坐標(biāo)和當(dāng)前坐標(biāo)兩個(gè)點(diǎn)就能畫出很短的直線,手指拖動(dòng)畫出的實(shí)際線條就是曲線了。
任意被拖拽的精靈是一個(gè)邏輯值,表示是否拖動(dòng)了精靈。
在手機(jī)上畫畫,最自然的方式莫過(guò)于直接用手指在手機(jī)屏幕上拖屏而畫。這需要在手指劃過(guò)的每一點(diǎn)上都留下過(guò)往的痕跡。從人的感知中,手指在屏幕上劃拖動(dòng)過(guò)程是一個(gè)連續(xù)的過(guò)程。 但計(jì)算機(jī)處理時(shí)實(shí)際上是將這個(gè)連續(xù)的過(guò)程分解為密集的離散采樣點(diǎn),就像線段是由點(diǎn)構(gòu)成的,只要采樣的頻率夠高、點(diǎn)夠密集,那么這些離散點(diǎn)看起來(lái)就像連續(xù)的線條(圖6)。
現(xiàn)在連上手機(jī),測(cè)試一下畫線和畫點(diǎn)功能是否正常吧。
剛才我們畫出的線條都是黑色的,下面以紅色畫筆為例,當(dāng)紅色按鈕被點(diǎn)擊時(shí),畫筆顏色改為紅色(圖7)。
通過(guò)RGB(紅、綠、藍(lán))三基色可以調(diào)出個(gè)性化的色彩。三基色的數(shù)值由文本(0-255)輸入框輸入,點(diǎn)擊按鈕確定,則合成顏色,并設(shè)置畫筆顏色(圖8)。
用滑動(dòng)條設(shè)置線寬,通過(guò)設(shè)置滑動(dòng)條的屬性限制線寬的范圍(圖9)。
點(diǎn)擊“圖像選擇框”,可以打開(kāi)手機(jī)相冊(cè)或文件夾,選擇圖片可以作為畫布背景用于涂鴉。注意是“選中項(xiàng)”而非“圖像”,“圖像”指的是我們上傳的文件夾圖標(biāo)(圖10)。
點(diǎn)擊拍照?qǐng)D標(biāo),調(diào)用相機(jī),當(dāng)拍照完成時(shí),將照片設(shè)置為畫布背景(圖11)。
當(dāng)點(diǎn)擊清除按鈕時(shí),直接調(diào)用清除畫布。直接調(diào)用畫布組件提供的“清除畫布”方法即可(圖12)。
完成作品后,需要保存為圖像文件。畫布組件提供了兩種圖像保存方法:不指定文件名的“保存”,以及由開(kāi)發(fā)者確定文件名的“另存”。這兩個(gè)方法模塊不能直接拼入按鈕的被點(diǎn)擊事件處理器中。這里需要借助控制模塊中的“求值但忽視結(jié)果”轉(zhuǎn)接模塊作為橋梁,才能拼接上。因?yàn)檫@兩種方法保存后都有一個(gè)返回值,而我們不需要這個(gè)返回值,所以用“求值但忽視結(jié)果”。
如果調(diào)用“保存”方法,開(kāi)發(fā)者不能指定保存的圖像文件名,系統(tǒng)會(huì)給它自動(dòng)命名。文件名的命名規(guī)則由“前綴app_ inventor_ +系統(tǒng)當(dāng)前時(shí)間值”構(gòu)成,存放的位置是SD卡中的“storage/emulated/0/Android/data/edu.mit.appinventor.aicompaion3/”目錄,這個(gè)文件名很難區(qū)分不同APP保存的圖像(圖13)。
如果調(diào)用“另存”方法,則保存的圖像文件名將是開(kāi)發(fā)者在參數(shù)槽中設(shè)置的文件名。但由于文件名是在開(kāi)發(fā)階段已經(jīng)確定,因此后面保存的圖像文件也會(huì)是同一個(gè),會(huì)覆蓋前面保存的文件(圖14)。
為了解決“另存”文件名一樣導(dǎo)致覆蓋之前作品的問(wèn)題,我們用計(jì)時(shí)器輔助生成不重復(fù)且好記的文件名(圖15)。
圖像在手機(jī)中的保存地址很復(fù)雜,如果你需要詳細(xì)地址,可以用對(duì)話框顯示出來(lái)(圖16)。
由于新版安卓安全權(quán)限方面的提升,老版的App Inventor可能會(huì)遇到某些手機(jī)照相機(jī)拍照無(wú)法獲取照片的問(wèn)題,這可以用打開(kāi)圖片文件的方法繞過(guò)去,也可以使用第三方升級(jí)擴(kuò)展包。
保存作品我們不知道放在了哪個(gè)文件夾,修改一下程序,保存時(shí)調(diào)用“畫布繪制文本”,讓文件路徑顯示在畫布上(圖17)。