上一篇我們解釋了 View 之間的關係跟結構。但 xml 的結構有個先天的限制,就是它雖然很適合描述靜態的巢狀結構但卻無法依據條件動態改變自己。這也是為什麼我們的範例一直都是靜態的,這時候就真的要寫一些 code 來改變這個世界了。
覺得期待嗎?開始動手前我們先一起看一下 java/
下有什麼檔案吧。
java
└── com
└── example
└── myapplication
└── MainActivity.kt
我們的 helloworld 程式只有一個 MainActivity.kt
,內容也很簡短如下:
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
跟 xml 依樣,按著 ⌘ 點擊
AppCompatActivity
,Android Studio 會帶你到AppCompatActivity
的 source code。
我們的 MainActivity
是繼承於 Activity
類別,這是 Android 所提供呈現畫面給使用者的四大元件之一(四大元件為:Activity、Service、Content Provider 和 Broadcast Receiver)
Activity 因為是跟畫面有關的元件,所以會有很多跟畫面狀態有關的生命週期(以及他所被呼叫的 callback 函式)需要了解,這裡我們引用官網的圖片做解釋:
https://developer.android.com/guide/components/images/activity_lifecycle.png
從 app 被打開到進入可使用的狀態依序是:
- onCreate
- onStart
- onResume
從可使用狀態到消失,依序是:
- onPause
- onStop
- onDestroy
會有三個階段的狀態是因為中間有些狀態可以返回其他狀態,以初學者來說我們只需要知道有這些狀態跟順序就可以了。
我們回頭看我們的 helloworld 發現我們只有複寫 onCreate
這個 function,而且只有一行程式碼:
setContentView(R.layout.activity_main)
R.layout.activity_main
是什麼呢?我們前一章節所提到的 activity_main.xml
在 compile 之後,會生成一個不重複的 id 編號在 R.layout
這個 class 底下。而 setContentView
是 Activity
提供的 function,讓 Activity
跟 xml 的 layout 可以透過 R
底下生成的 id 綁在一起。
我們之前所說 xml 不具互動性的缺點就可以透過 Activity
這一層來解決。解決的辦法就是綁定之後我們可以拿到 View
的實體,然後直接操作 View
做你需要的修改。
我們剛剛提到每個 layout 都會有個 int 的代表讓我們在程式端比較好連結, View 也有ㄧ樣的機制。我們先回到 activity_main.xml
找到我們想要獲取的 TextView
,幫他加個 id 如下所示:
<TextView
android:id="@+id/myTextView"
....../>
我們再回到 MainActivity
用剛剛建立的 id 可以在 Activity
這層拿到我們要的 myTextView
:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = findViewById<TextView>(R.id.myTextView)
textView.text = "Hello World!!"
}
findViewById
是標準的用法,但 kotlin 還提供更方便的 view binding,只要在 IDE 打 my 就會發現有 myTextView
這個變數可以直接使用如下:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myTextView.text = "Hello World!!"
}
眼尖的朋友會發現它自動幫我們加了一個 import 在 MainActivity
裡:
import kotlinx.android.synthetic.main.activity_main.*
這也是為什麼我們可以拿到 activity_main
下的所有 id reference。
既然這麼方便我們為什麼還要學標準的作法呢?每種好用的技術背後可能都會有些犧牲或前提,我們的前提就是
View
跟 class 必須一對一對應。如果 class 可以共用多個View
共用,不管 import 哪個都會有點怪。畢竟寫程式的最高宗旨就是相依性越少越好,如果可以 import 越少東西就會越安全。
除了設定文字以外,跟我們在 View 跟 xml 那篇提到的一樣,只要是 TextView 提供的函數我們都可以在 MainActivity
這邊設定。因為 Android Studio 的自動提示太強大,大家應該在打下 .
的時候就有發現了吧。
以上就是本篇內容囉,Activity
重要到我們一次講不完,下回我們會繼續讓我們的 helloworld 更具互動性,敬請期待。
Android 十全大補已經正式出書上架囉!
有興趣的讀者歡迎參考:
https://www.tenlong.com.tw/products/9789864345786
小弟最近剛開始接觸APP開發
覺得筆者大大的文章寫得清楚易懂,超讚!
不過實作到kotlin會自動幫我們binding id的部分
卻一直沒辦法找到我設定的id,想說是不是我哪裡漏了
上網爬文才發現原來Android Studio 4.1以上的版本
plugin kotlin-android-extensions 已經被google廢棄了?
現在推薦使用 ViewBinding 取代之
參考連結: https://blog.csdn.net/guolin_blog/article/details/113089706