第 16 章 應(yīng)用中的存儲

2018-02-24 15:51 更新

就像人類需要記憶一樣,應(yīng)用需要存儲。本章將探究如何在應(yīng)用中實現(xiàn)信息的存儲。

如果剛剛有人在電話里告訴你一家披薩店的電話號碼,你的大腦中會留下一段記憶;這時,如果有人大聲告訴你一串?dāng)?shù)字,并要你記住,你也會將它們保存到記憶中。在這種情況下,你未必能清楚地意識到,你的大腦是在保存或調(diào)用信息。

{%}

應(yīng)用同樣具備記憶功能,但它的內(nèi)在機(jī)制并不像大腦那樣神秘。本章你將學(xué)習(xí)如何設(shè)置應(yīng)用的存儲功能,如何利用它來保存信息,以及之后如何提取這些信息。

有名稱的存儲槽

應(yīng)用的存儲功能由一組有名稱的存儲槽(memory slots)組成。一旦組件被拖到應(yīng)用中,就會自動創(chuàng)建了一組被稱為“屬性”的存儲槽;也可以定義與特定組件無關(guān)的、有名稱的存儲槽,即變量。如果說屬性通常與應(yīng)用的外觀呈現(xiàn)有關(guān),那么變量則被認(rèn)為是應(yīng)用中不可見的“暫時”記憶。

屬性

在應(yīng)用中,組件,或者說像Button、TextBox以及Canvas這類可視組件,構(gòu)成了完整的用戶界面。而組件本身的外觀則是又一組屬性來確定,屬性值就保存在存儲槽中。

在組件設(shè)計器中,可以直接對屬性的存儲槽進(jìn)行修改,如圖16-1所示。

{%}

圖 16-1 在屬性欄中修改存儲槽來改變應(yīng)用的外觀

圖16-1中的Canvas組件具有六個屬性:BackgroundColor及PaintColor是保存顏色的存儲槽,BackgroundImage保存了文件名(kitty.png),Visible屬性保存了一個布爾值(true或false,依賴于是否勾選了方框),而Width及Height屬性保存了一個數(shù)字或某個特定的設(shè)置(如,“Fill parent”)。

在組件設(shè)計器中設(shè)置組件的屬性,相當(dāng)于設(shè)置應(yīng)用啟動時的外觀。應(yīng)用的最終用戶從未見過應(yīng)用中有一個名字為Height、值為300的存儲槽,他們只能看見用戶界面上有一個300像素高的組件。

定義變量

像屬性一樣,變量也是被命名的存儲槽,只是與特定的組件無關(guān)。在應(yīng)用中,需要記住某個狀態(tài),如果無法用組件的屬性來保存它,就需要定義一個變量來保存它。例如,一個游戲類的應(yīng)用可能需要記住玩家到達(dá)的等級。如果等級數(shù)用Label組件來顯示,就不需要定義變量,因為Label組件的Text屬性可以用來保存這個等級。但是,如果等級數(shù)不需要顯示給用戶,就應(yīng)該定義一個變量來保存它。

另一個使用變量的例子是第8章總統(tǒng)測驗。在這個應(yīng)用中,用戶界面上一次只能顯示一道測驗題,而其他問題用戶是看不見的,因此,就需要定義一個問題列表的變量來保存它們。

在組件設(shè)計器中拖入一個組件,它的屬性就自動創(chuàng)建完成了,相比之下,變量的定義需要在塊編輯器中直接拖出一個變量初始化塊(initialize global name to),點擊塊中的“name”為變量命名,并為變量設(shè)置初始值,方法是拖出一個塊放入變量初始化塊中,可以是number塊、text塊、color塊或者是make a list塊。跟隨下面的步驟就可以創(chuàng)建一個叫做score的初始值為0的變量。

1. 從塊編輯器的Built-in分組中找到Variables,點擊打開抽屜并拖出“initialize global name to”塊,如圖16-2所示。

{%}

圖 16-2 拖出變量初始化塊

2. 為變量命名:點擊變量初始化塊中的“name”,并輸入“score”,如圖16-3所示。

{%}

圖 16-3 為變量命名

3. 為變量設(shè)置初始值:從Math抽屜中拖出數(shù)字塊,將其插入變量初始化塊的插槽中,如圖16-4所示。

{%}

圖 16-4 為變量設(shè)初始值

4. 將變量初始值由默認(rèn)值(0)改為123,如圖16-5所示。

{%}

圖 16-5 修改變量的初始值

定義一個變量,就是通知應(yīng)用建立一個有名稱的存儲槽,來保存某個值。像屬性一樣,這些存儲槽用戶是看不見的。

變量的初始值在應(yīng)用啟動時就已經(jīng)被放入存儲槽中??梢杂脭?shù)字或文本對變量進(jìn)行初始化,除此之外,也可以插入一個“make a list”塊,它告訴應(yīng)用這個變量是一個存儲槽的列表,而不是一個單獨的值。關(guān)于list的更多內(nèi)容請參考第19章。

設(shè)置及讀取變量

變量定義之后,App Inventor會生成兩個屬于這個變量的塊:set塊及get塊,只要將鼠標(biāo)懸停在變量初始化塊中的變量名稱之上,就可以呼出到這兩個塊。如圖16-6所示。

{%}

圖 16-6 變量初始化塊包含訪問該變量的set塊及get塊

其中的“set global score to”塊可以用來修改(設(shè)置)變量的值,例如圖16-7中,將數(shù)字塊5放在變量score的set塊中。變量初始化塊中的“global”一詞意為“全局的”,指的是變量的適用范圍,一個全局變量可以被程序中所有事件處理程序及過程所引用。新版的App Inventor中還可以定義一種“l(fā)ocal”變量,這種變量可以在一個事件處理程序或某個過程的內(nèi)部進(jìn)行定義(這里暫不涉及)。

{%}

圖 16-7 將數(shù)字5賦給變量score

另一個“get global score”塊用于從變量中讀取變量值。例如,如果你想檢查score的值是否大于或等于100,就可以將“get global score”塊插入if塊進(jìn)行測試,如圖16-8所示。

{%}

圖 16-8 使用get global score塊來獲取變量值

用表達(dá)式為變量賦值

可以用單一的數(shù)字5來為變量賦值,不過通常會用一個更為復(fù)雜的表達(dá)式來為變量賦值(“表達(dá)式”是一個計算機(jī)科學(xué)的術(shù)語,即公式)。例如,在總統(tǒng)測試的應(yīng)用中,用戶點擊“下一題”按鈕時,要讓變量currentQuestionIndex的值增加1,來顯示下一道題;又如在游戲類應(yīng)用中,如果玩家失敗,還有可能將他的成績減10分;還有像第3章打地鼠的游戲中,通過改變變量x的值,實現(xiàn)地鼠在Canvas中水平位置的隨機(jī)移動。因此可以用若干個塊組成的表達(dá)式插入“set global score”塊為變量score賦值。

變量的遞增

一種最常見的表達(dá)式可能是變量的遞增,或根據(jù)變量的當(dāng)前值進(jìn)行設(shè)定。例如,游戲中當(dāng)玩家獲勝一次,變量score就將增加5,如16-9顯示了實現(xiàn)這一行為需要的塊。

{%}

圖 16-9 分?jǐn)?shù)變量遞增5

如果能夠理解這些塊的含義,你就離程序員又近了一步。這些塊可以理解為“讓成績在現(xiàn)有的值上加1”,這是變量遞增的另一種說法。要理解這些塊的工作機(jī)制,需要按照從內(nèi)向外、而不是從左到右的順序,最里面的塊是“get global score”及數(shù)字“5”,它們是最基礎(chǔ)的塊,然后“+”塊執(zhí)行加法運算,并將結(jié)果設(shè)定為變量score的值。

假設(shè)存儲槽中score的當(dāng)前值為5,經(jīng)過這些塊的運算,程序執(zhí)行了以下步驟:

1. 從score的存儲槽中讀取當(dāng)前值5;

2. 加上5得到結(jié)果10;

3. 將10放回到score的存儲槽中(來替代5)。

關(guān)于變量遞增的更多內(nèi)容請參見第19章。

構(gòu)造復(fù)雜的表達(dá)式

在Math抽屜中(圖16-10),App Inventor提供了許多數(shù)學(xué)函數(shù),就像在電子表格或計算器中見到的一樣。

{%}

圖 16-10 Math抽屜中的運算符及函數(shù)

你可以使用這些塊來構(gòu)造復(fù)雜的表達(dá)式,并將它們作為賦值表達(dá)式插入到“set global to”塊中。例如,要想實現(xiàn)一個圖片精靈(image sprite)在canvas范圍內(nèi)的隨機(jī)水平移動,就需要使用一個乘法塊(*)、一個減法塊(-)一個Canvas.Width屬性以及一個隨機(jī)小數(shù)函數(shù)來組織表達(dá)式,如圖16-11所示。

{%}

圖 16-11 使用數(shù)學(xué)(Math)塊來構(gòu)造上面的復(fù)雜表達(dá)式

正如在前面變量遞增的例子中所說,程序?qū)@些塊的解釋是遵循從內(nèi)而外的順序。假設(shè)Canvas的Width屬性值為300,ImageSprite的Width為50,程序?qū)?zhí)行以下步驟:

1. 分別從Canvas1.Width及ImageSprite.Width的存儲槽中讀取300及50;

2. 減法運算:300 - 50 = 250;

3. 調(diào)用隨機(jī)小數(shù)函數(shù)獲得一個1-1之間的隨機(jī)數(shù)(比如說0.5);

4. 乘法運算:250 * 0.5 = 125;

5. 將125放在ImageSprite.x屬性的存儲槽中。

顯示變量

在前面的例子中,修改一個組件的屬性,將直接影響到用戶界面的外觀,而變量則不然,改變一個變量并不會直接影響到應(yīng)用的外觀。如果你只是將變量score的值遞增,而不設(shè)法修改用戶界面的話,用戶永遠(yuǎn)都不知道變化的存在,就像俗話說的“樹木落入森林”一般:如果沒有人知道它,怎么證明它的存在呢?

有時,當(dāng)變量變化時,不希望在用戶界面上立即顯示出來,例如,在游戲中,可能會記錄某些統(tǒng)計結(jié)果(如失敗次數(shù)),只有游戲結(jié)束時才會顯示其結(jié)果。

與組件的屬性相比,這是使用變量來存儲數(shù)據(jù)的優(yōu)勢:可以在需要的時間顯示必要的數(shù)據(jù),也可以使應(yīng)用中的計算與用戶界面分離,這樣做的結(jié)果是更易于稍后對用戶界面的修改。

例如,在游戲中,可以將成績直接保存在Label的Text屬性中,也可以保存在變量中。如果保存在Label中,得分時可以讓Label的Text屬性值遞增,用戶可以直接看到成績的變化;如果成績被保存到變量中,并用變量的遞增記錄得分,則需要另外設(shè)置塊,將變量值顯示到Label中。

盡管使用變量保存并顯示數(shù)據(jù)要多出一些步驟,但當(dāng)你決定要修改應(yīng)用,以不同的方式在用戶界面上顯示成績時,變量的方法讓改變很容易實現(xiàn)。你不必對每個顯示組件上的成績進(jìn)行修改,它們不需要修改,你只需要修改那些與顯示有關(guān)的塊。

使用Label而非變量的方法,會讓應(yīng)用變得難于修改,因為,比如說要用一個遞增的值來控制label的寬度(Width),每一次遞增都要執(zhí)行一次對Width屬性的修改。

小結(jié)

應(yīng)用啟動之后,開始執(zhí)行一系列的操作,并對發(fā)生的事件進(jìn)行響應(yīng)。在事件響應(yīng)過程中,應(yīng)用有時需要記住一些東西,如,游戲中每個選手的成績,或者某個對象的移動方向等。

應(yīng)用可以用組件的屬性來實現(xiàn)存儲,但當(dāng)你需要與組件無關(guān)的存儲槽時,就需要定義變量??梢詫⒅当4娴阶兞恐校部梢詮淖兞恐凶x取當(dāng)前值,就像使用組件的屬性一樣。

無論是屬性值,還是變量值,對用戶來說都是不可見的。如果你想讓用戶看到保存在變量中的信息,只要添加塊,就可以用Label或其他用戶界面組件來顯示這些信息。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號