以文字組合建立簡單的應用程式

1. 事前準備

在這程式碼實驗室,您可以使用 Jetpack Compose 建立簡單的 Android 應用程式,並在螢幕上顯示生日訊息。

先決條件

  • 如何在 Android Studio 建立應用程式。
  • 如何在模擬器或 Android 裝置上執行應用程式。

課程內容

  • 如何編寫可組合函數,例如「Text」、「Column」和「Row」等可組合函數。
  • 如何在應用程式中顯示文字。
  • 如何設定文字格式,例如變更文字大小和字型大小。

建立內容

  • 這以文字格式顯示生日祝福的 Android 應用程式,完成後會如下所示:

1969df37dc980e41.png

軟硬體需求

  • 已安裝 Android Studio 的電腦。

2. 設定「生日快樂」應用程式

這任務中,您需要在 Android Studio 的「New Project」範本設定專案,並更改短信為個人化的生日祝福。

建立「Empty Compose Activity」專案

  1. 「歡迎使用 Android Studio」對話方塊中,選擇「New Project」
  2. 「New Project」對話方塊中,選擇「Empty Compose Activity」,然後按一下「Next」
  3. 「Name」欄位輸入「Happy Birthday」,然後在「Minimum SDK」欄位內,選擇最低 API 級別 21 (Lollipop),然後按一下「Finish」

86730c24681dd2fe.png

  1. 等待 Android Studio 建立專案檔案,而建立專案。
  2. 按一下fd26b2e3c2870c3.png「Run 'app'」

那應用程式應該如此螢幕截圖:

282f9427f60fcc5f.png

當您利用「Empty Compose Activity」範本建立這個「Happy Birthday」應用程式時,Android Studio 會提供基本 Android 應用程式所需的資源,包括畫面上的「Hello Android!」訊息。在這程式碼研究室,您可以瞭解如何建立訊息、變更文字為生日祝福語,以及新增及設定額外訊息的格式。

什麼是用戶介面 (UI)?

應用程式的用戶介面 (UI) 就是畫面上顯示的文字:文字、圖片、按鈕及許多其他類型的元素,以及這些元素在畫面上的顯示位置。這款應用程式會顯示應用程式向用戶顯示的內容,以及使用者如何與應用程式互動。

這個圖片包含可點擊的按鈕、訊息和文字輸入欄位,可供使用者輸入資料。

e5abb8ad9f9ae2a7.png

可點擊的按鈕

fded30871a8e0eca.png

訊息

aafb9c476f72d558.png

文字輸入欄位

這些元素都稱為 UI 元件。應用程式螢幕上顯示的內容幾乎為 UI 元素 (也稱為 UI 元件)。這類廣告可以是互動式,例如可點擊的按鈕或可編輯的輸入欄位,也可能是裝飾圖片。

在這個程式碼研究室中,您將透過名為「Text」元素的文字顯示用戶介面元素。

3. 什麼是 Jetpack Compose?

Jetpack Compose 是一種現代化的工具組,可用於建立 Android UI。Compose 提供簡單的程式碼、強大的工具和直覺式 Kotlin 功能,簡化並加快 Android 開發 UI 的流程。透過 Compose,您可以定義一組函式 (稱為「可撰寫」函式) 來建立使用者介面,藉此擷取資料並發出 UI 元素。

可撰寫的函式

可撰寫函式是 Compose 中用戶介面的基本構成要素。可組合的函式:

  • 說明用戶介面的某些部分。
  • 不傳回任何值。
  • 輸入及產生螢幕上顯示的內容。
  • 可能會產生多個 UI 元素。

備註

註解是用來在程式碼中附加額外資訊。這些資訊可協助 Jetpack Compose 編譯器等工具瞭解其他開發人員的應用程式程式碼。

請在名稱前加上註解名稱(註解) 並在後面加上 @ 這些字元會宣告在註解開頭。不同的屬性元素 (包括屬性、函式和類別) 可以加上註解。本課程稍後會介紹課程。

下圖為註解函式範例:

1009c41c49d58869.png

以下程式碼片段包含加註屬性範例。您會在接下來的程式碼研究室中使用這些功能。

// Example code, do not copy it over

@Json
val imgSrcUrl: String

@Volatile
private var INSTANCE: AppDatabase? = null

含有參數的註解

註解可以接受參數。針對處理這些工具的工具提供額外資訊。以下是含有及不含參數的 @preview 註解範例。

15169d39d744c179.png

缺少參數的註解

992de02d7b5dbfda.png

註解預覽背景

fbc159107d248a84.png

含有預覽標題的註解

您也可以將多個參數傳送至註解,如下所示。

510f8443a174f972.png

含有預覽標題和系統用戶介面的註解 (手機螢幕)

Jetpack Compose 包含各式各樣的內建註解,您已在課程中看過 @Composable@Preview 註解。本課程稍後將進一步說明註解及其用途。

可撰寫函式範例

可撰寫的函式會以 @Composable 註解加上註解。所有可編譯的函式都必須含有此註解。此註解會告知 Compose 編譯器,此函式是用來將資料轉換為 UI。提醒您,編譯器是一種特殊程式,會擷取您編寫的程式碼,逐行查看,並翻譯成電腦理解的內容 (機器語言)。

這個程式碼片段是簡單的可撰寫函式範例,該函式會傳送資料 (name 函式參數),並用於在螢幕上顯示文字元素。

@Composable
fun Greeting(name: String) {
   Text(text = "Hello $name!")
}

可撰寫函式的注意事項:

  • 可撰寫的函式可接受參數,讓應用程式邏輯描述或修改用戶介面。在這種情況下,您的 UI 元素會接受 String,以便透過用戶名稱進行歡迎。
  • 函式不會傳回任何內容。 可模擬 UI 的可撰寫函式無需傳回任何值,因為這些函式描述的是必要的畫面狀態,而不是建立使用者介面元素。換句話說,可調式函式只會描述 UI,不會建立或建立 UI,也不會傳回任何項目。

請注意程式碼中的可組合函式

  1. 在 Android Studio 中開啟 MainActivity.kt 檔案。
  2. 捲動至 DefaultPreview() 函式並刪除。新增可撰寫的函式 BirthdayCardPreview(),以便預覽 Greeting() 函式,如下所示。建議您一律為函式命名或重新命名,以描述其功能。
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
   BirthdayCardTheme {
       Greeting("Android")
   }
}

可撰寫的函式可以呼叫其他可撰寫的函式。在這個程式碼片段中,預覽函式會呼叫 Greeting() 可撰寫函式。

請注意,前一個函式還包含 @Preview 註解,且在 @Composable 註解之前設有參數。如要進一步瞭解本課程傳送到 Preview 註解的引數,請參閱這篇文章。

可組合的函式名稱

不傳回任何結果的撰寫函式,且該可提供 @Composable 註解,請使用 Palcal 大小寫命名。帕斯卡爾字母是指命名慣例中,每個詞的首字母大寫。「Pascal」和「l」的大小寫不同,則「大寫字母」中的所有字詞皆是大寫。使用 came 首字母大寫時,第一個字詞不會大寫。

撰寫函式:

  • 必須為名詞:DoneButton()
  • 不是動詞或動詞:DrawTextField()
  • 表示名詞:TextFieldWithLink()
  • 不是形容詞:Bright()
  • 副詞:Outside()
  • 名詞 MAY 的前置字元是以描述性為形容詞:RoundIcon()

此規範適用於函式是否觸發 UI 元素。詳情請參閱可命名的函式

範例程式碼請勿複製

// Do: This function is a descriptive PascalCased noun as a visual UI element
@Composable
fun FancyButton(text: String) {

// Do: This function is a descriptive PascalCased noun as a non-visual element
// with presence in the composition
@Composable
fun BackButtonHandler() {

// Don't: This function is a noun but is not PascalCased!
@Composable
fun fancyButton(text: String) {

// Don't: This function is PascalCased but is not a noun!
@Composable
fun RenderFancyButton(text: String) {

// Don't: This function is neither PascalCased nor a noun!
@Composable
fun drawProfileImage(image: ImageAsset) {

4. Android Studio 中的設計窗格

Android Studio 可讓您在 IDE 中預覽可組合的功能,而不必將應用程式安裝至 Android 裝置或模擬器。如同先前課程所述,您可以在 Android Studio 的「設計」窗格中預覽應用程式的外觀。

74e6261fc023772b.png

可撰寫的函式必須支援任何參數的預設值,才能進行預覽。因此,您無法直接預覽 Greeting() 函式。而必須新增其他函式 (在此案例中為 BirthdayCardPreview() 函式) ,並使用適當的參數呼叫 Greeting() 函式。

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
   BirthdayCardTheme {
       Greeting("Android")
   }
}

建議您於後續程式碼研究室的 Preview 註解中瞭解 showBackground 參數。

如何預覽預覽畫面:

  1. 建立程式碼

預覽畫面會自動更新。

另一種更新或刷新整理預覽畫面的方法,就是在「設計」窗格中按一下 fdd133641cfac2b3.png [建立及刷新整理]

5cec5263ba04ea1.png

  1. BirthdayCardPreview() 函式中,將 Greeting() 函式中的「Android"」引數變更為您的姓名。
fun BirthdayCardPreview() {
   BirthdayCardTheme {
       Greeting("James")
   }
}
  1. 在「設計」窗格中按一下 fdd133641cfac2b3.png [建立及刷新整理]

你應該會看到更新後的預覽畫面。

ac506881708bb7fb.png

5. 新增文字元素

在這項工作中,您將移除 Hello Android! 問候語,並新增生日問候語。

新增可組合的函式

  1. MainActivity.kt 檔案中,刪除 Greeting() 函式定義。您可以新增自己的函式,以便日後在程式碼研究室中顯示問候語。
@Composable
fun Greeting(name: String) {
   Text(text = "Hello $name!")
}
  1. 請注意,Android Studio 會醒目顯示 Greeting() 函式呼叫,然後將遊標懸停在這個函式呼叫上以找出錯誤。

問候語功能醒目顯示,其中有未解決的錯誤彈出式視窗

  1. onCreate()BirthdayCardPreview() 函式中刪除 Greeting() 函式呼叫及其引數。您的 MainActivity.kt 檔案看起來會像這樣:
class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           BirthdayCardTheme {
               // A surface container using the 'background' color from the theme
               Surface(color = MaterialTheme.colors.background) {
               }
           }
       }
   }
}

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview(){
   BirthdayCardTheme {
   }
}
  1. BirthdayCardPreview() 函式之前,新增名為 BirthdayGreetingWithText() 的函式。別忘了在函式之前加上 @Composable 註解,否則將會產生 Text 可撰寫的撰寫函式。
@Composable
fun BirthdayGreetingWithText() {
}
  1. BirthdayGreetingWithText() 可撰寫的函式中,加入 String 類型的 message 參數。
@Composable
fun BirthdayGreetingWithText(message: String) {
}
  1. BirthdayGreetingWithText() 函式中,新增 Text() 可組合式文字訊息,做為命名的引數。
@Composable
fun BirthdayGreetingWithText(message: String) {
    Text(
       text = message
    )
}

這個 BirthdayGreetingWithText() 函式會在用戶介面中顯示文字。方法是呼叫 Text() 可撰寫的函式。

預覽函式

在這項工作中,您將在「設計」窗格中預覽 BirthdayGreetingWithText() 函式。

  1. 呼叫 BirthdayCardPreview() 函式中的 BirthdayGreetingWithText() 函式。
  2. String 引數傳遞至 BirthdayGreetingWithText() 函式 (向好友發出的生日問候語)。 您可以視需要自訂名稱,例如 "Happy Birthday Sam!"
@Preview(showBackground = false)
@Composable
fun BirthdayCardPreview() {
   BirthdayCardTheme {
       BirthdayGreetingWithText( "Happy Birthday Sam!")
   }
}
  1. 在 [設計] 窗格中,按一下 ea3433426a37f49b.png [建立與刷新整理] ,然後等待版本完成預覽您的函式。

84f2d40e0e0e9289.png

6. 變更字型大小

您已將文字新增至用戶介面,但似乎還沒有最終應用程式。在這項工作中,您會瞭解如何變更大小、文字顏色和其他影響文字元素外觀的屬性。您也可以嘗試不同的字型大小和顏色。

可縮放像素

可縮放像素 (SP) 是字型大小的測量單位。Android 應用程式中的 UI 元素會採用兩種度量單位:密度獨立像素 (DP) - 您稍後將用於版面配置和可擴充像素 (SP)。根據預設,SP 單位的大小與 DP 單位相同,但系統會根據手機設定中偏好的文字大小調整其大小。

  1. MainActivity.kt 檔案中,捲動至 BirthdayGreetingWithText() 函式中的 Text() 組合。
  2. Text() 函式傳遞為 fontSize 引數做為第二個已命名引數,並設為 36.sp
Text(
   text = message,
   fontSize = 36.sp
)

Android Studio 會醒目顯示 .sp 程式碼,因為您需要匯入某些類別或屬性來編譯應用程式。

6b6e60b13e085a13.png

  1. 按一下「Android Studio」醒目顯示的 .sp
  2. 按一下彈出式視窗中的 [匯入] ,即可匯入 androidx.compose.ui.unit.sp 以使用 .sp 擴充功能屬性。

sp 程式碼具有匯入動作未解析的彈出式視窗。

  1. 捲動至檔案頂端,然後發現 import 陳述式,其中會顯示 import androidx.compose.ui.unit.sp 陳述式,表示 Android Studio 會將套件加入檔案。

1631e626a2c9e1b8.png

  1. 在「設計」窗格中按一下 [建立與刷新整理] ,即可查看更新後的預覽畫面。請注意問候語預覽畫面的字型大小變更。

顯示建立與刷新整理選項

你現在可以測試不同的字型大小。

7. 新增其他文字元素

您在先前的工作中,新加入的祝賀訊息已傳送給好友。在這項工作中,您必須以姓名簽署卡片。

  1. MainActivity.kt 檔案中,捲動至 BirthdayGreetingWithText() 函式。
  2. 將函式傳送至 String 類型的 from 參數以做為簽名。
fun BirthdayGreetingWithText(message: String, from: String)
  1. 在生日訊息 Text 可撰寫之後,請新增另一個 Text 可組合,可接受設為 from 值的 text 引數。
Text(
   text = from
)
  1. 新增 fontSize 已命名引數集,並將值設為 24.sp
Text(
   text = from,
   fontSize = 24.sp
)
  1. 捲動至 BirthdayCardPreview() 函式。
  2. 新增其他 String 引數來簽署卡片,例如 "- from Emma"
BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
  1. 按一下設計窗格中的 [建立與刷新整理]
  2. 請注意預覽。

62bc7bf80421de5d.png

可撰寫的函式可能會發出多個 UI 元素。不過,如果您沒有提供如何排列這些元素的指示,Compose 可能會以您偏好的方式排列元素。舉例來說,先前的程式碼會產生兩個相互重疊的文字元素,因為對於如何安排兩種組合,沒有相關指示。

後續工作將讓您學習如何在資料列和資料欄中排列合成項目。

8. 排列資料列和欄中的文字元素

UI 階層

UI 階層以集合為基礎,代表一個元件可包含一或多個元件,有時也會用到父項和子項。此處的結構定義為上層 UI 元素包含子項 UI 元素,而這些 UI 元素可能包含子項 UI 元素。本節將說明「欄」、「列」和「方塊」的元件,這些元件可以當做上層 UI 元素。

9270b7e10f954dcb.png

Compose 中的三個基本標準版面配置元素是 ColumnRowBox 可組合元件。歡迎造訪下一個程式碼研究室,進一步瞭解 Box 元件。

畫面上有三個垂直排列的元素,一列顯示三個排列的元素

ColumnRowBox 是可撰寫的函式,會將可撰寫的內容當成引數,因此您可以將項目放在這些版面配置元素中。舉例來說,Row 組合中的每個子元素會水平並排放置。

// Don't copy.
Row {
    Text("First column")
    Text("Second column")
}

在這張圖片中,這些文字元素會在螢幕上的相鄰顯示。

藍色框線僅供示範之用,無法顯示。

20c50a01cc9aa4cb.png

結尾的 lambda 語法

請注意,在先前的程式碼片段中,大括號使用大括號,而不是 Row 可撰寫函式中的括號。這就是所謂的「Trailing Lambda 語法」。本課程稍後將為您詳細介紹 lambdas 和結尾的 lambda 語法。現在,熟悉常用的撰寫語法。

最後一個函式是函式時,Kotlin 提供的特殊語法可將參數傳遞給函式。

6373d65802273065.png

如要將函式做為參數傳遞,您可以使用結尾的 lambda 語法。請將括號置於函式名稱後方,而不要在括號內加入函式名稱。這是「撰寫」中的常見做法,因此您必須熟悉程式碼的外觀。

舉例來說,Row() 可撰寫函式中的最後一個參數是 content 參數,該函式會輸出子項 UI 元素。假設您想建立一個包含三個文字元素的資料列。這個程式碼有效,但相當麻煩:

Row(
    content = {
        Text("Some text")
        Text("Some more text")
        Text("Last text")
    }
)

由於 content 參數是函式簽名中的最後一個參數,且您會將其值視為 lambda 運算式,但如果您不知道 lambda 的運作方式,只要熟悉語法,即可確定沒問題。請依照以下方式移除 content 參數和括號:

Row {
    Text("Some text")
    Text("Some more text")
    Text("Last text")
}

排列資料列的文字元素

在這項工作中,您會妥善地排列應用程式中的文字元素,以免重疊。

  1. MainActivity.kt 檔案中,捲動至 BirthdayGreetingWithText() 函式。
  2. 在文字元素周圍加上 Row 可撰寫的內容,使資料欄顯示兩個文字元素。

現在,函式看起來應該會像這樣:

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
   Row{
       Text(
           text = message,
           fontSize = 36.sp,
       )
       Text(
           text = from,
           fontSize = 24.sp,
       )
   }
}
  1. 在醒目顯示的程式碼片段中按一下 Row
  2. 請注意,Android Studio 提供多種 Row 匯入選項。
  3. 按一下 [匯入]

資料列函式醒目顯示兩個彈出式視窗,分別顯示未解決的錯誤

  1. androidx.compose.ui開頭以 Row(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.Argument.Horizontal, androidx....

dfad9fcfae49aa7a.png

  1. 按一下 [建立 & 刷新] 即可更新「設計」 窗格中的預覽畫面。

彼此相鄰的生日問候語和簽名。

現在沒有重疊時,預覽畫面會看起來更好。不過,由於簽名空間不足,所以這不是必要步驟。在下一個工作中,您可以安排資料欄中的文字元素來解決這個問題。

排列資料欄中的文字元素

在這項工作中,您需變更 BirthdayGreetingWithText() 函式來排列資料欄中的文字元素。請記得按一下 [建立並重新整理] 來更新預覽畫面,您應該會看到以下螢幕截圖:

生日問候語和簽名會顯示在一個欄中的一欄。

您已經自行嘗試檢查程式碼,現在可以透過此程式碼段裡的解決方案程式碼來檢查您自己的程式碼:

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
   Column {
       Text(
           text = message,
           fontSize = 36.sp,
       )
       Text(
           text = from,
           fontSize = 24.sp,
       )
   }
}

當 Android Studio 出現提示時,請匯入這個套件:

import androidx.compose.foundation.layout.Column

9. 裝置上顯示

如果對預覽感到滿意,就可以開始在裝置或模擬器上執行應用程式。

  1. MainActivity.kt 檔案中,捲動至 onCreate() 函式。
  2. Surface 區塊呼叫 BirthdayGreetingWithText() 函式。
  3. 傳送 BirthdayGreetingWithText() 函式,以及您的生日問候語和簽名。

完成的 onCreate() 函式應會如下所示:

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           BirthdayCardTheme {
               // A surface container that uses the 'background' color from the theme
               Surface(color = MaterialTheme.colors.background) {
                   BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
               }
           }
       }
   }
}
  1. 在模擬器上建立並執行應用程式。

1969df37dc980e41.png

10. 取得解決方案程式碼

已完成的MainActivity.kt

package com.example.android.happybirthday

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import com.example.happybirthday.ui.theme.HappyBirthdayTheme

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           HappyBirthdayTheme {
               // A surface container that uses the 'background' color from the theme
               Surface(color = MaterialTheme.colors.background) {
                   BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
               }
           }
       }
   }
}

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
   Column {
       Text(
           text = message,
           fontSize = 36.sp,
       )
       Text(
           text = from,
           fontSize = 24.sp,
       )
   }
}

@Preview(showBackground = false)
@Composable
fun BirthdayCardPreview() {
   HappyBirthdayTheme {
       BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
   }
}

11. 結語

您已建立「生日快樂」應用程式。

在接下來的程式碼研究室中,您可以為應用程式新增圖片,然後調整文字元素的對齊方式,藉此美化文字。

摘要

  • Jetpack Compose 是用於建立 Android UI 的新型工具包。Jetpack Compose 能以更簡單的程式碼、強大的工具和符合直覺的 Kotlin API,簡化並加快 Android 上的 UI 開發作業。
  • 應用程式的用戶介面 (UI) 是指畫面上顯示的文字:文字、圖片、按鈕,以及許多其他類型的元素。
  • 可撰寫函式是 Compose 的基本構成要素。可撰寫的函式可用於說明用戶介面的部分內容。
  • 可撰寫的函式會以 @Composable 註解加註;此註解會告知 Compose 編譯器,此函式是用來將資料轉換為 UI。
  • Compose 中的三個基本標準版面配置元素為 ColumnRowBox。這些是可撰寫的函式,可用於撰寫可撰寫的內容,因此您可以將這些項目加入其中。例如,Row 中的每個子項都可以相鄰放置。

瞭解詳情