這邊真的是幫你上最後一份按鈕了啦。
想遙遠的按鈕系列的第一篇,有說到希望最後的樣子是會長這個樣子:
畢竟他的專案名稱還是叫做「DiceRoller」我們還是要給他一點 respect ,Respect you know?
那就今天就讓這個系列做一個完整的結束,GOGOGOGO!
餓死胎頭,要將昨天做完中間又大又直白的阿拉伯數字~~(但其實阿拉伯數字是印度的婆羅米人發明的)~~,換成對應點數的骰子圖案。
改革總是伴隨著犧牲與付出,我們必須在這裡跟我們摯愛的朋友 TextView 說再見,感謝他讓我們更好理解程式的運行狀況,TextView 總是在第一線赤裸裸地被使用者觀看,背後又有大群程式需要靠他顯示,如此偉大的 object 最終要離開我們,讓我們懷念他。
在我們狠狠低把 TextView 甩到一邊去之後,就是 ImageView 要來頂替這個重要的位子了,就如同傑克失去左手之後,把草帽交給魯夫一樣,顯示結果這個重責大任就交給 ImageView 了。
把 Image 拖進來之後 Android Studio 會讓你選擇你想要的 resource,我們還沒有骰子的圖,所以我們先放 avatars 作為臨時圖片。
畢竟我們的大哥 TextView 被甩到旁邊去了,APP 裡的一些 object 也失去了與大哥的連結(限制),完成上面步驟之後還是得為 ImageView 加一點限制,這邊我們有開另一篇文章跟大家解釋過了,就不多講啦。
但就算添加了一些限制之後,ImageView 仍存在一條警告,我們會在之後處理他,先不用擔心。
這邊提供一個連結,給各位下載骰子圖片使用,不用擔心是甚麼奇怪的網址,因為這是從google developer 那邊找到的。載完解壓縮就可以準備丟進 Android Studio 啦。
你可以點最左邊的 Resource Manager 的標籤,再點「+」找到你要丟進來的圖片,中間沒有甚麼要調的設定,看到下面這樣的圖就是完成啦:
再來就是把 avatars 替換成骰子圖片啦,進入 attribute 裡找到帶有板手的 srcCompat (還記得ㄇ,帶有板手的就是只有開發者會看到,使用者是看不到的喔),將圖片替換成 dice 的任一個圖片應該會看到下列這樣情況:
好...好大>///<
稍微調整一下大小,不要讓 APP 一直忍,調整完之後就可以進入程式修改的環節啦,進入 MainActivity.kt 之後會有一堆錯誤等著你,你可能會很緊張,
為甚麼這樣子?你拉著我說你有些錯誤。
別擔心,是大哥留下來的痕跡,我們還沒有去除而已。
private fun rollDice(){
val dice = Dice(6)
val diceRoll = dice.roll()
val resultTextView: TextView = findViewById(R.id.textView)
resultTextView.text = rollDice.toString()
}
原來是我們仍在引用 R.id.textView ,讓 Andriod Studio 找不到他,著急的向你求救。把他刪除之後錯誤訊息就都會消失了。
讓我們在同樣的位子補上 ImageView :
val diceImage: ImageView = findViewById(R.id.imageView) //宣告diceImage
如果你想測試一下的話你可以將這段程式寫在下方:
diceImage.setImageResource(R.drawable.dice_2) //點擊按鈕之後會把目前的image更改為dice_2
目前的程式碼跟昨天的程式碼就差在 TextView 換成了 ImageView ,點擊按鈕後修改 TextView 的 text 跟直接換上圖片,這樣的差距,其他監聽或是產生亂數的都還好好的躺著。
之前有稍微介紹過條件式 if-else 與 when ,接下來會用這樣的條件式去判斷 diceRoll 這個變數接收到的數字為多少,再換上對應的圖片。那我們如果以 if-else 的方式下去寫的話就是:
if (diceRoll == 1){
diceImage.setImageResource(R.drawable.dice_1)
}else if (diceRoll == 2){
diceImage.setImageResource(R.drawable.dice_2)
}else if (diceRoll ==3){
...
}else {
...
會發現重複的程式碼一直出現,如果這時候改用 when 來處理呢?
when (diceRoll) {
1 -> diceImage.setImageResource(R.drawable.dice_1)
2 -> diceImage.setImageResource(R.drawable.dice_2)
3 -> diceImage.setImageResource(R.drawable.dice_3)
4 -> diceImage.setImageResource(R.drawable.dice_4)
5 -> diceImage.setImageResource(R.drawable.dice_5)
6 -> diceImage.setImageResource(R.drawable.dice_6)
}
when 語句可以更簡潔的完成相同的邏輯。
將這段語法放進宣告 diceImage 的下方,整個 APP 就正式完成啦!最後補上完整程式碼:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.button2)
rollButton.setOnClickListener {
Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT).show()
rollDice()
}
}
private fun rollDice(){
val dice = Dice(6)
val diceRoll = dice.roll()
val diceImage: ImageView = findViewById(R.id.imageView) // 宣告diceImage
when (diceRoll) {
1 -> diceImage.setImageResource(R.drawable.dice_1)
2 -> diceImage.setImageResource(R.drawable.dice_2)
3 -> diceImage.setImageResource(R.drawable.dice_3)
4 -> diceImage.setImageResource(R.drawable.dice_4)
5 -> diceImage.setImageResource(R.drawable.dice_5)
6 -> diceImage.setImageResource(R.drawable.dice_6)
}
}
}
class Dice(private val numSides: Int){ //numSides這個參數代表骰子會有的面數
fun roll(): Int {
return (1..numSides).random() //回傳 1~骰子面數的隨機數字
}
}
最後的最後是不是忘記了甚麼,不能跟小智一樣對比雕說我辦完事馬上回來,結果一拋棄就是拋棄22年。
壞。
還有 contentDescription 的問題要去處理,再按按鈕更新圖片之後,ImageView 的內容描述也要跟著更新,內容應該為當前骰子的數量。要記得補上去喔~
diceImage.contentDescription = diceRoll.toString()
骰子按鈕系列就終於是結束啦,我在想是不是該拉回正題,還是我就繼續這樣慢慢學,把正題留到下次參賽,但我還是會寫一些跟題目會使用到的功能啦。
今天先 John ,
下一篇見寫寫打家打家擺掰。