1. 事前準備

如要瞭解如何使用各種 Android 平台 API,實作社群網路應用程式中的常見功能,SociaLite 是絕佳的參考範例。這款應用程式運用各式 Jetpack API 實現複雜功能,不僅可在更多裝置上穩定運作,也能減少編寫程式碼的需求。

本程式碼研究室會逐步引導您製作與 Android 15 無邊框強制措施相容的 SociaLite 應用程式,並確保這款無邊框應用程式能回溯相容。採用無邊框設計後,SociaLite 會如下圖所示,具體情形因裝置和操作模式而異:

  • 具備 Kotlin 基本知識。
  • 完成「 設定 Android Studio 」程式碼研究室,或熟悉 Android Studio 使用方式,且能在搭載 Android 15 的模擬器或實體裝置上測試應用程式。
  • 如何因應 Android 15 的無邊框措施更動。
  • 如何讓無邊框應用程式回溯相容。
  • 軟硬體需求

  • 最新版 Android Studio。
  • 搭載 Android 15 Beta 1 以上版本的測試裝置或模擬器。
  • Android 15 Beta 1 以上版本的 SDK。
  • 您也可以複製整個存放區,然後查看 codelab_improve_android_experience_2024 分支。

    $ git clone git@github.com:android/socialite.git
    $ cd socialite
    $ git checkout codelab_improve_android_experience_2024
    
  • 在 Android Studio 中開啟 SociaLite,然後在 Android 15 裝置或模擬器上執行該應用程式。您會看到類似下方的畫面:
  • 如何因應 Android 15 的無邊框措施更動

    在 Android 15 之前,應用程式的 UI 預設會受到限制,即使處於展開狀態,也不會延伸到狀態列和導覽列這類系統資訊列區塊。雖然您可以選擇採用無邊框設計,但因應用程式各不相同,這項操作可能既瑣碎又麻煩。

    所幸,從 Android 15 開始,應用程式都會預設採用「無邊框」設計。您會看到以下預設設定:

  • 三按鈕導覽列呈現透明狀態。
  • 手勢導覽列呈現透明狀態。
  • 狀態列呈現透明狀態。
  • 除非是套用了插邊或邊框間距,否則內容會在系統資訊列後方繪製,例如在導覽列、狀態列和說明文字列之後。
  • 這可確保在提升應用程式品質時,一定會採用無邊框設計,並讓打造無邊框應用程式的過程更輕鬆。不過,此更動對應用程式可能不是全然有益。我們之後會舉例說明您將目標 SDK 升級為 Android 15 後,對 SociaLite 造成的兩項負面影響。

    將目標 SDK 值改為 Android 15

  • 在 SociaLite 應用程式的 build.gradle 檔案中,將目標和編譯 SDK 版本更改為 Android 15 或 VanillaIceCream
  • 如果您學習這個程式碼研究室課程時,Android 15 還未推出穩定版,程式碼會如下所示:

    android {
        namespace = "com.google.android.samples.socialite"
        compileSdkPreview = "VanillaIceCream"
        defaultConfig {
            applicationId = "com.google.android.samples.socialite"
            minSdk = 21
            targetSdkPreview = "VanillaIceCream"
    

    如果您學習這個程式碼研究室課程時,Android 15 已推出穩定版,程式碼會如下所示:

    android {
        namespace = "com.google.android.samples.socialite"
        compileSdk = 35
        defaultConfig {
            applicationId = "com.google.android.samples.socialite"
            minSdk = 21
            targetSdk = 35
    
  • 重新建構 SociaLite,留意下列問題:
  • 三按鈕操作模式下的背景保護措施與導覽列不符。在手勢操作模式下,「Chats」畫面會自動採用無邊框設計,您不必執行任何操作。但在三按鈕操作模式下,您應移除畫面的背景保護措施。
  • 如要移除三按鈕操作模式預設的背景保護措施,請執行下列步驟:

  • MainActivity.kt 檔案中移除預設的背景保護措施,方法是將 window.isNavigationBarContrastEnforced 屬性設為 false。
  • class MainActivity : ComponentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            installSplashScreen()
            super.onCreate(savedInstanceState)
            setContent {
                // Add this block:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    window.isNavigationBarContrastEnforced = false
    

    window.isNavigationBarContrastEnforced 屬性可確保導覽列的對比度夠強,能因應全透明背景的要求。您只要將這個屬性設為 false,就能有效將三按鈕操作模式的背景設為透明。window.isNavigationBarContrastEnforced 只會在三按鈕操作模式下發揮效果,不會影響手勢操作模式。

  • 在 Android 15 裝置上重新執行應用程式,查看任一對話。「Timeline」、「Chats」和「Settings」畫面現在都會顯示為無邊框。而應用程式的 NavigationBar (含有「Timeline」、「Chats」和「Settings」按鈕) 會在系統透明的三按鈕導覽列後方繪製。
  • 在 SociaLite 中,InputBar 會被遮住。實際上,如果您將裝置旋轉到橫向模式,或使用大螢幕裝置,可能會發現畫面四周的元素都遭到遮蓋。因此,請針對上述所有使用情況,考量如何處理插邊。就 SociaLite 而言,您可以套用邊框間距,將 InputBar 中可輕觸的內容調到上方位置。

    如要套用插邊以修正 UI 遭遮蔽的問題,請採取以下步驟:

  • 前往 ui/chat/ChatScreen.kt 檔案,在第 178 行左右找出 ChatContent 可組合函式,其中含有對話畫面的 UI。ChatContent 會利用 Scaffold 輕鬆建構 UI。根據預設,Scaffold 可提供系統 UI 相關資訊 (例如系統資訊列的深度) 做為插邊,供您搭配使用 Scaffold 的邊框間距值 (innerPadding 參數)。請使用 ScaffoldinnerPadding,將邊框間距新增到 InputBar 中。
  • 在第 214 行左右找出 ChatContent 中的 InputBar。這個自訂的可組合函式可建立 UI,供使用者撰寫訊息。以下是輸入列的預覽畫面:
  • InputBar 採用了 contentPadding,並將其當做邊框間距,套用到含有其餘 UI 的 Row 可組合函式中。這個邊框間距會套用到 Row 可組合函式的每個邊。您可以在第 432 行左右發現這點。以下是供您參考的 InputBar 可組合函式 (請不要新增這段程式碼):

    // Don't add this code because it's only for reference.
    @Composable
    private fun InputBar(
        contentPadding: PaddingValues,
        Surface(...) {
            Row(
                modifier = Modifier
                    .padding(contentPadding)
                IconButton(...) { ... } // take picture
                IconButton(...) { ... } // attach picture
                TextField(...) // write message
                FilledIconButton(...){ ... } // send message
    
  • 返回 ChatContent 中的 InputBar,然後變更 contentPadding,以便使用系統資訊列插邊。您可以在第 220 行左右查看此操作。
  • InputBar(
        contentPadding = innerPadding, //Add this line.
        // contentPadding = PaddingValues(0.dp), // Remove this line.
    
  • 在 Android 15 裝置上重新執行應用程式。
  • 套用底部邊框間距後,按鈕就不會再被系統資訊列遮住,但是這也同時套用了頂部邊框間距,其中涵蓋 TopAppBar 和系統資訊列的深度。Scaffold 會將邊框間距值傳遞給自身內容,以便避開頂部應用程式列和系統資訊列。

  • 如要修正頂部邊框間距,請建立 innerPadding PaddingValues 副本,將頂部邊框間距設為 0.dp,然後將修改的副本傳遞到 contentPadding 中。
  • InputBar(
        contentPadding = innerPadding.copy(layoutDirection, top = 0.dp), //Add this line.
        // contentPadding = innerPadding, // Remove this line.