iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 5
0

上一篇我們解釋了 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。

Activity

我們的 MainActivity 是繼承於 Activity 類別,這是 Android 所提供呈現畫面給使用者的四大元件之一(四大元件為:ActivityServiceContent ProviderBroadcast Receiver

Lifecycle

Activity 因為是跟畫面有關的元件,所以會有很多跟畫面狀態有關的生命週期(以及他所被呼叫的 callback 函式)需要了解,這裡我們引用官網的圖片做解釋:

https://developer.android.com/guide/components/images/activity_lifecycle.png

從 app 被打開到進入可使用的狀態依序是:

  1. onCreate
  2. onStart
  3. onResume

從可使用狀態到消失,依序是:

  1. onPause
  2. onStop
  3. onDestroy

會有三個階段的狀態是因為中間有些狀態可以返回其他狀態,以初學者來說我們只需要知道有這些狀態跟順序就可以了。

我們回頭看我們的 helloworld 發現我們只有複寫 onCreate 這個 function,而且只有一行程式碼:

setContentView(R.layout.activity_main)

R.layout.activity_main 是什麼呢?我們前一章節所提到的 activity_main.xml 在 compile 之後,會生成一個不重複的 id 編號在 R.layout 這個 class 底下。而 setContentViewActivity 提供的 function,讓 Activity 跟 xml 的 layout 可以透過 R 底下生成的 id 綁在一起。

我們之前所說 xml 不具互動性的缺點就可以透過 Activity 這一層來解決。解決的辦法就是綁定之後我們可以拿到 View 的實體,然後直接操作 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 十全大補] View 跟 xml
下一篇
[Android 十全大補] User Interaction
系列文
Android 十全大補30

尚未有邦友留言

立即登入留言