第8章的“總統(tǒng)測驗”可以被定制成各種測驗,但這種定制只對App Inventor程序員有用。只有程序員可以修改問題和答案,而對于父母、老師或其他用戶來說,他們無法創(chuàng)建一個測驗或變換問題(除非他們也學(xué)App Inventor?。?/p>
本章將構(gòu)建一個“出題”應(yīng)用,“老師”可以在輸入表單中創(chuàng)建試題。試題和答案將被存儲在Web數(shù)據(jù)庫中,以便“學(xué)生”可以單獨訪問“答題”應(yīng)用并參加考試。通過創(chuàng)建這兩個應(yīng)用,你會在概念上產(chǎn)生更大的飛躍,并學(xué)習(xí)如何創(chuàng)建一個應(yīng)用,讓用戶自行生成數(shù)據(jù),并實現(xiàn)用戶之間跨應(yīng)用的數(shù)據(jù)共享。
“出題”與“答題”這兩個應(yīng)用協(xié)同工作,讓“老師”可以為“學(xué)生”出題。父母可以在長途旅行中做一些旅行花絮類的應(yīng)用,以增加孩子們的樂趣;小學(xué)教師可以創(chuàng)建“數(shù)學(xué)突擊”一類的小測驗;而大學(xué)生們可以創(chuàng)建一系列的測驗,幫助他們的學(xué)習(xí)小組來準(zhǔn)備期末考試。本章建立在第8章“總統(tǒng)測驗”的基礎(chǔ)上,如果你還沒學(xué)過,在繼續(xù)本章之前,請先學(xué)習(xí)第8章。
本章將設(shè)計兩個應(yīng)用:針對“老師”的“出題”應(yīng)用(見圖10-1)以及針對“學(xué)生”的“答題”應(yīng)用。在“出題”應(yīng)用中:
用戶在輸入表單中輸入問題及答案;
顯示輸入的一對問答;
圖 10-1 出題應(yīng)用
“答題”應(yīng)用的功能與之前的“總統(tǒng)測驗”類似。事實上,是以“總統(tǒng)測驗”為起點創(chuàng)建“答題”應(yīng)用,不同的是,這里的問題是使用“出題”應(yīng)用輸入并保存在數(shù)據(jù)庫中的。
“總統(tǒng)測驗”是一個使用靜態(tài)數(shù)據(jù)的應(yīng)用范例:不管用戶做多少次測驗,問題都是一樣的,因為問題被寫在程序中(稱為“硬編碼”)。新聞應(yīng)用、博客以及像Facebook和Twitter這類的社交網(wǎng)絡(luò)應(yīng)用采用的是動態(tài)數(shù)據(jù),這意味著數(shù)據(jù)隨時在改變。通常這種動態(tài)信息由用戶生成,這類應(yīng)用允許用戶輸入、修改并共享信息。在“出題”與“答題”應(yīng)用中,將學(xué)習(xí)創(chuàng)建一個應(yīng)用,來處理用戶生成的數(shù)據(jù)。
在第9章“木琴”應(yīng)用中,我們首次引入動態(tài)列表概念:用戶輸入的音符被記錄在列表中。由用戶生成數(shù)據(jù)的應(yīng)用更為復(fù)雜,而且使用的塊也更抽象,因為沒有預(yù)設(shè)的靜態(tài)數(shù)據(jù)可供參照。盡管可以定義列表變量,但不能設(shè)置具體的項。在編寫程序的同時,需要設(shè)想最終用戶輸入的數(shù)據(jù)被添加到列表中。
本章涵蓋了App Inventor中的如下內(nèi)容:
輸入表單:允許用戶輸入信息;
顯示來自多個列表的數(shù)據(jù)項;
永久保存數(shù)據(jù):“出題”應(yīng)用將問題和答案保存到網(wǎng)絡(luò)數(shù)據(jù)庫中,“答題”應(yīng)用將從同一個數(shù)據(jù)庫中加載它們;
登陸App Inventor網(wǎng)站,創(chuàng)建新項目“MakeQuiz”,屏幕標(biāo)題設(shè)為“出題”,并連接到測試手機或模擬器。
使用組件設(shè)計器來創(chuàng)建用戶界面,如圖10-2所示(圖的后面有更詳細(xì)的說明),組件清單列于表10-1中。從Palette中拖出組件,將名稱改為表中的命名。注意,標(biāo)題Label的名稱(Label1 – Label3)不必改,就用它們的默認(rèn)值(因為在編輯器中不會使用這些名稱)。
表10-1 “出題”應(yīng)用中的所有組件
組件類型 | 面板中分組 | 命名 | 作用 |
---|---|---|---|
TableArrangement | Layout | TableArrangement1 | 格式化表單,包括問題及答案 |
Label | User Interface | Label1 | 提示“問題:” |
TextBox | User Interface | QuestionText | 用戶在此輸入問題 |
Label | User Interface | Label2 | 提示“答案:” |
TextBox | User Interface | AnswerText | 用戶在此輸入答案 |
Button | User Interface | SubmitButton | 用戶點擊提交問題-答案對兒 |
Label | User Interface | Label3 | 顯示“測驗的問題及答案?!?/td> |
Label | User Interface | QuestionAnswersLabel | 顯示之前輸入的成對的問題答案 |
TinyWebDB | Storage | TinyWebDB1 | 用數(shù)據(jù)庫保存并提取數(shù)據(jù) |
圖 10-2 組件設(shè)計器中的“出題”應(yīng)用
按以下方式設(shè)置組件屬性:
1. 設(shè)置Text屬性:Label1為“問題:”,Label2為“答案:”,Label3為“試題及答案”;
2. 設(shè)置Label3的字號為18,并勾選FontBold屬性;
3. 設(shè)置QuestionText的Hint屬性為“輸入問題”,AnswerText的Hint屬性為“輸入回答”;
4. 設(shè)置SubmitButton的Text屬性為“提交”;
5. 設(shè)置QuestionsAnswersLabel的Text屬性為“試題及答案”;
6. 將QuestionText、AnswerText以及與它們相關(guān)的Label移入TableArrangement1。
在“總統(tǒng)測驗”中,首先定義了兩個全局列表變量QuestionList和AnswerList,本章中無需為這兩個變量提供預(yù)設(shè)的問題和答案,如圖10-3所示。
圖 10-3 列表變量初始化
需要注意,與“總統(tǒng)測驗“不同的是,這兩個列表沒有定義列表項,因為“出題”及“答題”應(yīng)用中,所有數(shù)據(jù)都將由用戶創(chuàng)建(即動態(tài)的、用戶生成的數(shù)據(jù))。
首先來處理用戶的輸入行為。具體來說,當(dāng)用戶輸入問題和答案并點擊提交時,程序要向列表中添加數(shù)據(jù)項來更新QuestionList和AnswerList,如下圖所示:
圖 10-4 向列表中添加新項
向列表中添加項,意味著向列表的末尾追加新項。如圖10-4,程序從QuestionText和AnswerText文本框中獲取用戶輸入的內(nèi)容,并分別被追加到相應(yīng)的列表中。
向列表中添加的項更新了列表變量QuestionList和AnswerList,但用戶看不到任何變化。第三行的塊用來顯示這個變化:用冒號將兩個列表的內(nèi)容連接起來。默認(rèn)情況下,App Inventor用小括號來包圍列表內(nèi)容,列表項之間用空格間隔,像這樣:(item1 item2 item3)。當(dāng)然,這不是顯示列表的理想方式,只是暫時用來測試程序的行為。稍后我們將用更高級的方式來顯示列表,即,每對問題答案各占一行。
回憶一下在“總統(tǒng)測驗”中,當(dāng)移動到下一題時,要清空上一題的回答結(jié)果。在本應(yīng)用中,當(dāng)用戶提交了一對問題-答案后,同樣要清空QuestionText及AnswerText文本框,以便準(zhǔn)備下一題的輸入,如下圖所示:
圖 10-5 提交問題-答案之后清空文本框
用戶提交的問題-答案,將分別被添加到各自的列表中,并顯示出來,這時QuestionText和AnswerText中的文本被清空,如圖10-5所示。請注意,可以復(fù)制一個有內(nèi)容的文本塊(如上圖中的“:”塊),通過刪除塊中的文本,來獲得一個空的文本塊。
現(xiàn)在是以App Inventor的默認(rèn)格式來顯示問題及答案。假如有一個有關(guān)州首府的測驗,已經(jīng)輸入了兩對問題-答案,則顯示成: (加州首府在哪? 紐約州首府在哪?):(薩克拉門托 奧爾巴尼)。
可以想像,如果測驗中的問題很多,結(jié)果會顯得非?;靵y。理想的顯示方式,應(yīng)該是每行只顯示一對問題-答案:
加州首府在哪? 薩克拉門托
紐約州首府在哪? 奧爾巴尼
第20章講述了單個列表中項的逐行顯示技術(shù),在繼續(xù)學(xué)習(xí)之前,可以去閱讀一下。
這里的任務(wù)稍顯復(fù)雜,因為涉及到兩個列表。為了應(yīng)對這種復(fù)雜性,需要創(chuàng)建過程displayQAs,并從SubmitButton.Click事件處理程序中調(diào)用該過程。
逐行顯示問題-答案,需要做到以下幾點:
使用foreach塊遍歷QuestionList中的每個問題;
使用變量answerIndex,在遍歷問題的同時,獲取與問題對應(yīng)的答案;
過程displayQAs封裝了所有用于顯示數(shù)據(jù)的塊,如圖10-6所示,在需要顯示列表時,可直接調(diào)用displayQAs,而不必再重復(fù)使用過程內(nèi)部的塊。
圖 10-6 創(chuàng)建displayQAs過程
由于foreach塊只能遍歷一個列表,而本應(yīng)用中有兩個列表,因此要求在遍歷問題列表的同時,為每個問題選擇對應(yīng)的答案。這需要定義一個索引變量,就像第8章“總統(tǒng)測試”中的currentQuestionIndex一樣,這里定義了answerIndex,當(dāng)foreach遍歷QuestionList時,用來跟蹤對應(yīng)的答案在列表AnswerList中的位置。
在foreach開始遍歷之前,設(shè)answerIndex的值為1;在foreach遍歷過程中,answerIndex用來從AnswerList中選擇當(dāng)前問題的答案,然后遞增1。在foreach的每次迭代中,當(dāng)前的問題-答案被添加到QuestionsAnswersLabel的最后一行,問題與答案之間以冒號分隔。
已經(jīng)創(chuàng)建了顯示問題-答案的過程displayQAs,但在調(diào)用它之前,它起不到任何作用。修改SubmitButton.Click事件處理程序,用displayQAs替代對QuestionsAnswersLabel.Text的簡單設(shè)置,來顯示所有的問題-答案。更新后的塊如圖10-7所示。
更多建議: