- Android編程權(quán)威指南(第4版)
- (美)克莉絲汀·馬西卡諾 布賴(lài)恩·加德納 比爾·菲利普斯 克里斯·斯圖爾特
- 1171字
- 2021-06-15 15:29:09
2.4 更新控制器層
在上一章,應(yīng)用控制器層的MainActivity類(lèi)的處理邏輯很簡(jiǎn)單:顯示定義在activity_main.xml文件中的布局對(duì)象,為兩個(gè)按鈕設(shè)置監(jiān)聽(tīng)器,響應(yīng)用戶(hù)點(diǎn)擊事件并創(chuàng)建toast消息。
既然現(xiàn)在有更多的地理知識(shí)問(wèn)題可以檢索與展示,MainActivity類(lèi)就需要更多的處理邏輯來(lái)讓GeoQuiz應(yīng)用的模型層與視圖層協(xié)作。
打開(kāi)MainActivity.kt文件,如代碼清單2-5所示,創(chuàng)建一個(gè)Question對(duì)象集合以及該集合的索引變量。
代碼清單2-5 增加Question對(duì)象集合(MainActivity.kt)
class MainActivity : AppCompatActivity() {
private lateinit var trueButton: Button
private lateinit var falseButton: Button
private val questionBank = listOf(
Question(R.string.question_australia, true),
Question(R.string.question_oceans, true),
Question(R.string.question_mideast, false),
Question(R.string.question_africa, false),
Question(R.string.question_americas, true),
Question(R.string.question_asia, true))
private var currentIndex = 0
...
}
這里,我們通過(guò)多次調(diào)用Question類(lèi)的構(gòu)造函數(shù),創(chuàng)建了Question對(duì)象集合。
(在較復(fù)雜的項(xiàng)目里,這類(lèi)集合的創(chuàng)建和存儲(chǔ)會(huì)單獨(dú)處理。在后續(xù)應(yīng)用開(kāi)發(fā)中,你會(huì)看到更好的模型數(shù)據(jù)存儲(chǔ)方式。現(xiàn)在,簡(jiǎn)單起見(jiàn),我們選擇在控制器層代碼中創(chuàng)建集合。)
要在屏幕上顯示一系列地理知識(shí)問(wèn)題,可以使用questionBank、currentIndex變量以及Question對(duì)象的存取方法。
如代碼清單2-6所示,首先給TextView和新Button添加屬性,然后引用它們,并設(shè)置TextView顯示當(dāng)前集合索引所指向的地理知識(shí)問(wèn)題(稍后會(huì)設(shè)置NEXT按鈕的點(diǎn)擊事件監(jiān)聽(tīng)器)。
代碼清單2-6 使用TextView(MainActivity.kt)
class MainActivity : AppCompatActivity() {
private lateinit var trueButton: Button
private lateinit var falseButton: Button
private lateinit var nextButton: Button
private lateinit var questionTextView: TextView
...
override fun onCreate(savedInstanceState: Bundle?) {
...
trueButton = findViewById(R.id.true_button)
falseButton = findViewById(R.id.false_button)
nextButton = findViewById(R.id.next_button)
questionTextView = findViewById(R.id.question_text_view)
trueButton.setOnClickListener { view: View ->
...
}
falseButton.setOnClickListener { view: View ->
...
}
val questionTextResId = questionBank[currentIndex].textResId
questionTextView.setText(questionTextResId)
}
}
保存所有文件,確保沒(méi)有錯(cuò)誤發(fā)生,然后運(yùn)行GeoQuiz應(yīng)用。可以看到,集合存儲(chǔ)的第一個(gè)問(wèn)題顯示在TextView上了。
現(xiàn)在來(lái)處理NEXT按鈕,為其設(shè)置監(jiān)聽(tīng)器View.OnClickListener。該監(jiān)聽(tīng)器的作用是讓集合索引遞增并相應(yīng)地更新TextView的文本內(nèi)容,如代碼清單2-7所示。
代碼清單2-7 使用新增的按鈕(MainActivity.kt)
override fun onCreate(savedInstanceState: Bundle?) {
...
falseButton.setOnClickListener { view: View ->
...
}
nextButton.setOnClickListener {
currentIndex = (currentIndex + 1) % questionBank.size
val questionTextResId = questionBank[currentIndex].textResId
questionTextView.setText(questionTextResId)
}
val questionTextResId = questionBank[currentIndex].textResId
questionTextView.setText(questionTextResId)
}
注意到了嗎?同樣的questionTextView文字賦值代碼出現(xiàn)在了兩個(gè)不同的地方。參照代碼清單2-8,花點(diǎn)兒時(shí)間把這樣的公共代碼放到一個(gè)函數(shù)里,然后分別在nextButton監(jiān)聽(tīng)器里以及onCreate(Bundle?)函數(shù)的末尾調(diào)用它。后一個(gè)調(diào)用是為了初始化設(shè)置activity視圖中的文本。
代碼清單2-8 使用updateQuestion()封裝公共代碼(MainActivity.kt)
class MainActivity : AppCompatActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... nextButton.setOnClickListener { currentIndex = (currentIndex + 1) % questionBank.sizeval questionTextResId = questionBank[currentIndex].textResIdquestionTextView.setText(questionTextResId)updateQuestion() }val questionTextResId = questionBank[currentIndex].textResIdquestionTextView.setText(questionTextResId)updateQuestion() } private fun updateQuestion() { val questionTextResId = questionBank[currentIndex].textResId questionTextView.setText(questionTextResId) } }
運(yùn)行GeoQuiz應(yīng)用,驗(yàn)證新添加的NEXT按鈕。
如果一切正常,問(wèn)題應(yīng)該已經(jīng)完美顯示出來(lái)了。當(dāng)前,GeoQuiz應(yīng)用認(rèn)為所有問(wèn)題的答案都是true,下面著手修正這個(gè)邏輯錯(cuò)誤。同樣,為避免代碼重復(fù),我們將解決方案封裝在一個(gè)私有函數(shù)里。
要添加到MainActivity類(lèi)的函數(shù)如下:
private fun checkAnswer(userAnswer: Boolean)
該函數(shù)接受布爾類(lèi)型的變量參數(shù),判別用戶(hù)點(diǎn)擊了TRUE還是FALSE按鈕。然后,將用戶(hù)的答案同當(dāng)前Question對(duì)象中的答案做比較,判斷正誤,并生成一個(gè)toast消息反饋給用戶(hù)。
在MainActivity.kt文件中,添加checkAnswer(Boolean)函數(shù)的實(shí)現(xiàn)代碼,如代碼清單2-9所示。
代碼清單2-9 增加checkAnswer(Boolean)函數(shù)(MainActivity.kt)
class MainActivity : AppCompatActivity() {
...
private fun updateQuestion() {
...
}
private fun checkAnswer(userAnswer: Boolean) {
val correctAnswer = questionBank[currentIndex].answer
val messageResId = if (userAnswer == correctAnswer) {
R.string.correct_toast
} else {
R.string.incorrect_toast
}
Toast.makeText(this, messageResId, Toast.LENGTH_SHORT)
.show()
}
}
在按鈕的監(jiān)聽(tīng)器里,調(diào)用checkAnswer(Boolean)函數(shù),如代碼清單2-10所示。
代碼清單2-10 調(diào)用checkAnswer(Boolean)函數(shù)(MainActivity.kt)
override fun onCreate(savedInstanceState: Bundle?) { ... trueButton.setOnClickListener { view: View ->Toast.makeText(this,R.string.correct_toast,Toast.LENGTH_SHORT).show()checkAnswer(true) } falseButton.setOnClickListener { view: View ->Toast.makeText(this,R.string.correct_toast,Toast.LENGTH_SHORT).show()checkAnswer(false) } ... }
運(yùn)行GeoQuiz應(yīng)用,確認(rèn)toast消息基于用戶(hù)點(diǎn)擊給出了正確反饋。
- MySQL數(shù)據(jù)庫(kù)應(yīng)用與管理 第2版
- C語(yǔ)言程序設(shè)計(jì)實(shí)訓(xùn)教程
- Getting Started with CreateJS
- 數(shù)據(jù)結(jié)構(gòu)(Python語(yǔ)言描述)(第2版)
- SQL 經(jīng)典實(shí)例
- Mastering Akka
- ArcGIS for Desktop Cookbook
- Practical GIS
- Modernizing Legacy Applications in PHP
- Instant GLEW
- Software Architecture with Python
- Manage Your SAP Projects with SAP Activate
- C++ Data Structures and Algorithm Design Principles
- MonoTouch應(yīng)用開(kāi)發(fā)實(shí)踐指南:使用C#和.NET開(kāi)發(fā)iOS應(yīng)用
- 程序員的算法趣題2