Compose for Wear OS 程式碼研究室

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

1. 簡介

4d28d16f3f514083.png

借助 Compose for Wear OS,您可以將在使用 Jetpack Compose 建構應用程式中習得的知識,應用到穿戴式裝置。

Compose for Wear OS 內建「Material You」設計支援,可簡化及加速使用者介面開發作業,協助您用較少的程式碼建立精美的應用程式。

在這個程式碼研究室中,我們希望您能對 Compose 有些基本瞭解,但不需要達到精通的境界。

您可以建立多種 Wear 專屬可組合內容 (包括簡易與複雜),最後,您可開始自行編寫適用於 Wear OS 的應用程式。立即開始!

學習目標

  • 與先前使用 Compose 的經驗同異處
  • 簡易可組合函式以及其在 Wear OS 上的運作方式
  • Wear OS 特定可組合內容
  • Wear OS 的 LazyColumn (ScalingLazyColumn))
  • Wear OS 的 Scaffold 版本

建構目標

您會建構一個簡單的應用程式,顯示已針對 Wear OS 最佳化處理的可組合函式捲動式清單。

由於您使用 Scaffold,系統也會在頂端顯示弧形文字時間、暈影,最後顯示與裝置端連動的捲動指標。

完成本程式碼研究室後,您建立的資訊主頁會如下所示:

20971cc341c73076.gif

必要條件

2. 開始設定

在這個步驟中,您會設定環境並下載範例專案。

您需要準備的項目

  • 最新的 Android Studio 穩定版
  • Wear OS 裝置或模擬器 (剛開始使用嗎?這裡有設定方式的說明。)

下載程式碼

如果您已安裝 Git,只要執行下列指令即可複製這個存放區的程式碼。如要檢查 Git 是否已安裝完成,請在終端機或指令列中輸入 git --version 類型,並確認其可正確執行。

git clone https://github.com/googlecodelabs/compose-for-wear-os.git
cd compose-for-wear-os

如果您沒有 Git,可以點選下方按鈕,以下載這個程式碼研究室的所有程式碼:

您隨時都可變更工具列中的執行設定,以在 Android Studio 中執行任一模組。

b059413b0cf9113a.png

在 Android Studio 中開啟專案

  1. 在「Welcome to Android Studio」視窗中,選取 c01826594f360d94.png「Open an Existing Project」
  2. 選取資料夾 [Download Location]
  3. Android Studio 匯入專案後,請測試是否能在 Wear OS 模擬器或實體裝置上執行 startfinished 模組。
  4. start 模組應如以下螢幕截圖所示。您會在該處執行所有工作。

d6d4b92ac53d9b3e.png

探索範例程式碼

  • build.gradle 包含基本的應用程式設定。其包括建立 Composable Wear OS 應用程式所需的依附元件。我們將探討 Jetpack Compose 與 Wear OS 兩種版本的同異處。
  • main > AndroidManifest.xml 包含建立 Wear OS 應用程式所需的元素。這與非 Compose 應用程式相同,且與行動應用程式類似,因此我們不會進行審查。
  • main > theme/ 資料夾包含 Compose 用於主題的 ColorTypeTheme 檔案。
  • main > MainActivity.kt 包含用於透過 Compose 建立應用程式的樣板。其中也包含我們應用程式的頂層可組合內容 (例如 ScaffoldScalingLazyList)。
  • main > ReusableComponents.kt 包含我們將要建立的大部分 Wear 特定可組合內容函式。我們將會在這個檔案中執行眾多作業。

3. 查看依附元件

您對 Wear 相關依附元件所進行的大部分變更會位於架構層頂端 (以下方紅框醒目標示)。

d92519e0b932f964.png

這表示許多搭配 Jetpack Compose 使用的依附元件,在 Wear OS 版本還是可以繼續沿用。舉例來說,您可以使用相同的使用者介面、執行階段、編譯器和動畫依附元件。

不過,先前使用的程式庫就不一定適用了,您必須採用適當的 Wear OS MaterialFoundationNavigation 程式庫。

您可透過下方的比較協助釐清差異:

Wear OS 依附元件(androidx.wear.*)

比較

標準依附元件(androidx.*)

androidx.wear.compose:compose-material

而非

androidx.compose.material:material

androidx.wear.compose:compose-navigation

而非

androidx.navigation:navigation-compose

androidx.wear.compose:compose-foundation

除了

androidx.compose.foundation:foundation

1. 開發人員可繼續使用如漣漪材質等其他材質相關程式庫,以及透過 Wear Compose Material 程式庫延伸的質感設計圖示。

開啟 build.gradle,在 start 模組中搜尋「TODO: Review Dependencies」。(這個步驟只是要查看依附元件,您將不會新增任何程式碼。)

start/build.gradle:

// TODO: Review Dependencies
// General Compose dependencies
implementation "androidx.activity:activity-compose:$activity_compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation "androidx.compose.material:material-icons-extended:$compose_version"

// Compose for Wear OS Dependencies
implementation "androidx.wear.compose:compose-material:$wear_compose_version"

// Foundation is additive, so you can use the standard version in your Wear OS app.
implementation "androidx.wear.compose:compose-foundation:$wear_compose_version"

您應會辨識眾多一般 Compose 依附元件,因此其不在我們的涵蓋範圍之列。

接著來看看 Wear OS 依附元件。

如前所述,系統只會納入 Wear OS 特定版本的 material (androidx.wear.compose:compose-material)。也就是說,您不會在專案中看到或包含 androidx.compose.material:material

請務必留意,您可以將其他材質程式庫與 Wear Material 搭配使用。我們實際上已在這個程式碼研究室中納入 androidx.compose.material:material-icons-extended,以實踐上述做法。

最後,我們納入適用於 Compose (androidx.wear.compose:compose-foundation) 的 Wear foundation 程式庫。這是附加內容,方便您與先前所用的標準 foundation 搭配使用。事實上,您也許已體認到我們在一般 Compose 依附元件中納入上述內容!

瞭解依附元件之後,我們來看看主要應用程式。

4. 查看 MainActivity

我們會在

start

模組中執行所有工作,因此請確認在模組中開啟每個檔案。

首先,請在 start 模組中開啟 MainActivity

這個相當簡單的類別延伸了 ComponentActivity,並使用 setContent { WearApp() } 來建立使用者介面。

根據您先前對 Compose 的瞭解,這對您來說應並不陌生。我們只是在設定使用者介面。

向下捲動至 WearApp() 可組合函式。在討論程式碼本身之前,您應會在整個程式碼中看到眾多的一整排的「TODO」,每個都代表本程式碼研究室中的步驟。您可以暫時忽略這些資訊。

如下所示:

趣味 WearApp() 中的程式碼:

WearAppTheme {
    // TODO: Swap to ScalingLazyListState
    val listState = rememberLazyListState()

    /* *************************** Part 4: Wear OS Scaffold *************************** */
    // TODO (Start): Create a Scaffold (Wear Version)

        // Modifiers used by our Wear composables.
        val contentModifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
        val iconModifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center)

        /* *************************** Part 3: ScalingLazyColumn *************************** */
        // TODO: Create a ScalingLazyColumn (Wear's version of LazyColumn)
        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(
                top = 32.dp,
                start = 8.dp,
                end = 8.dp,
                bottom = 32.dp
            ),
            verticalArrangement = Arrangement.Center,
            state = listState
        ) {

            // TODO: Remove item; for beginning only.
            item { StartOnlyTextComposables() }

            /* ******************* Part 1: Simple composables ******************* */
            item { ButtonExample(contentModifier, iconModifier) }
            item { TextExample(contentModifier) }
            item { CardExample(contentModifier, iconModifier) }

            /* ********************* Part 2: Wear unique composables ********************* */
            item { ChipExample(contentModifier, iconModifier) }
            item { ToggleChipExample(contentModifier) }
        }

    // TODO (End): Create a Scaffold (Wear Version)

}

首先請設定主題 WearAppTheme { }。操作方式與您先前撰寫的內容完全相同,亦即以顏色、字體排版和圖形來設定 MaterialTheme

不過針對 Wear OS,我們通常建議使用針對圓形與非圓形裝置最佳化的預設 Material Wear 圖形,因此若您深入瞭解 theme/Theme.kt,則會發現我們並未覆寫圖形。

若有需要,您可開啟 theme/Theme.kt 進一步探索,不過一樣與之前相同。

接下來,我們會為將要建構的 Wear 可組合項建立一些修飾符,如此就無需每次皆加以指定。其主要是以內容為中心,並增加一些邊框間距。

接著我們會建立 LazyColumn,以用來為各種項目產生垂直捲動清單,就跟您之前的操作一樣。

程式碼:

item { StartOnlyTextComposables() }

/* ******************* Part 1: Simple composables ******************* */
item { ButtonExample(contentModifier, iconModifier) }
item { TextExample(contentModifier) }
item { CardExample(contentModifier, iconModifier) }

/* ********************* Part 2: Wear unique composables ********************* */
item { ChipExample(contentModifier, iconModifier) }
item { ToggleChipExample(contentModifier) }

針對項目本身,僅有 StartOnlyTextComposables() 會產生任一使用者介面。(我們將會在整個程式碼研究室填入其餘部分)。

這些函式實際上是位於 ReusableComponents.kt 檔案,我們會於下節說明。

開始使用 Compose for Wear OS 吧!

5. 新增簡易的可組合函式

讓我們先來探討您可能已熟悉的三種可組合內容 (ButtonTextCard)。

首先,我們要移除 Hello World 可組合內容。

搜尋「TODO: Remove item」,然後清除留言和下一行:

步驟 1

// TODO: Remove item; for beginning only.
item { StartOnlyTextComposables() }

接著,讓我們來新增第一個可組合函式。

建立「按鈕」可組合項

start 模組中開啟 ReusableComponents.kt 並搜尋「TODO: Create a Button Composable」,將目前的可組合內容方法替換為此程式碼。

步驟 2

// TODO: Create a Button Composable (with a Row to center)
@Composable
fun ButtonExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Row(
        modifier = modifier,
        horizontalArrangement = Arrangement.Center
    ) {
        // Button
        Button(
            modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
            onClick = { /* ... */ },
        ) {
            Icon(
                imageVector = Icons.Rounded.Phone,
                contentDescription = "triggers phone action",
                modifier = iconModifier
            )
        }
    }
}

ButtonExample() 可組合內容 (此程式碼所在函式) 現會產生置中按鈕。

讓我們來逐步瞭解程式碼。

Row 在此僅用於將 Button 可組合內容置中於圓形螢幕。實際做法是套用我們在 MainActivity 中建立的修飾符,並將其傳遞至此函式。之後在圓形螢幕上捲動時,我們會希望確保內容不會遭到截斷,這就是其會置中的原因所在。

接下來,我們要建立 Button 本身。程式碼與之前用於「按鈕」的程式碼相同,但在本範例中我們會使用 ButtonDefault.LargeButtonSize。這些是針對 Wear OS 裝置最佳化的預設大小,因此請務必善加利用!

之後,我們會將點擊事件設為空白的 Lamba。這些可組合內容在本範例中僅供示範用途,因此將無需派上用場。不過在實際應用程式中,我們會使用諸如 ViewModel 的程式庫進行通訊,以執行商業邏輯。

接著會在按鈕當中設定「圖示」。此程式碼與先前看過的 Icon 相同。我們也會從 androidx.compose.material:material-icons-extended 程式庫下載圖示,

最後,我們會設定先前針對「圖示」所設定的修飾符。

若您執行此應用程式,看起來應會像這樣:

881cfe2dcdef5687.png

這是您之前已撰寫的程式碼 (非常好)。不同之處在於,您現會看見為 Wear OS 最佳化的按鈕。

一切皆相當直覺,讓我們來看看另一個主題吧。

建立「文字」可組合內容

ReusableComponents.kt 中搜尋「TODO: Create a Text Composable」,並將目前的可組合方法替換為本程式碼。

步驟 3

// TODO: Create a Text Composable
@Composable
fun TextExample(modifier: Modifier = Modifier) {
    Text(
        modifier = modifier,
        textAlign = TextAlign.Center,
        color = MaterialTheme.colors.primary,
        text = stringResource(R.string.device_shape)
    )
}

建立 Text 可組合內容、設定可組合內容修飾符、對齊文字、設定顏色,最後再透過字串資源設定文字內文。

Compose 開發人員對文字可組合內容應會感到非常熟悉,且程式碼實際上與您先前使用的程式碼完全相同。

其外觀如下:

b4f0e65e666cf3eb.png

TextExample() 可組合函式 (此程式碼所在函式) 現會以主要材質顏色產生「文字」可組合內容。

字串提取自 res/values/strings.xml 檔案。若您實際查看 res/values 資料夾,應會看到兩個 strings.xml 資源檔案。

Wear OS 為圓形和非圓形裝置提供字串資源,因此若使用正方形模擬器執行這個字串,該字串會改變:

9e133aea7cde78a6.png

到目前為止都很順利。我們來看看最後一個類似的可組合內容:Card

建立「卡片」可組合內容

ReusableComponents.kt 中搜尋「TODO: Create a Card」,並將目前的可組合方法替換為本程式碼。

步驟 4

// TODO: Create a Card (specifically, an AppCard) Composable
@Composable
fun CardExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    AppCard(
        modifier = modifier,
        appImage = {
            Icon(
                imageVector = Icons.Rounded.Message,
                contentDescription = "triggers open message action",
                modifier = iconModifier
            )
        },
        appName = { Text("Messages") },
        time = { Text("12m") },
        title = { Text("Kim Green") },
        onClick = { /* ... */ }
    ) {
        Text("On my way!")
    }
}

Wear 略有差異,其具有以下兩種主要的卡片:AppCardTitleCard

針對本範例,我們希望在卡片中使用 Icon,因此請使用 AppCard。(TitleCard 的運算單元數量較少,詳情請參閱「資訊卡」指南)。

我們會建立 AppCard 可組合項、設定可組合項修飾符、新增 Icon、新增數個 Text 可組合參數 (每個參數皆用於卡片中的不同空間),最後在結尾處設定主要內容文字。

其外觀如下:

430eaf85d8ee5883.png

此時,您可能會辨識到針對這些可組合項,Compose 程式碼的顯示方式和先前幾乎相同,對吧?您可以重複運用現有的所有知識!

讓我們看看一些新的可組合內容。

6. 新增 Wear 專屬可組合內容

我們將在本節中探索 ChipToggleChip 可組合內容。

建立「方塊」可組合內容

在材質指南中實際上已指定方塊,但在標準材質資料庫中並無實際的可組合函式。

方塊是一種快速、輕觸一下的動作,尤其適合螢幕空間有限的 Wear 裝置。

以下是 Chip 可組合函式的幾個不同版本,讓您瞭解可以建立的項目:

現在,我們就開始動手寫程式吧。

ReusableComponents.kt 中搜尋「TODO: Create a Chip」,並將目前的可組合方法替換為本程式碼。

步驟 5

// TODO: Create a Chip Composable
@Composable
fun ChipExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Chip(
        modifier = modifier,
        onClick = { /* ... */ },
        label = {
            Text(
                text = "5 minute Meditation",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        },
        icon = {
            Icon(
                imageVector = Icons.Rounded.SelfImprovement,
                contentDescription = "triggers meditation action",
                modifier = iconModifier
            )
        },
    )
}

Chip 可組合項使用的參數許多皆與用於其他可組合項 (修飾符和 onClick) 的參數相同,因此無須查看這些參數。

其還使用標籤 (我們為其建立了一個 Text 可組合內容) 和圖示。

Icon 程式碼看起來應與您在其他可組合項中看見的程式碼完全相同,但針對本程式碼,我們會從 androidx.compose.material:material-icons-extended 程式庫中提取 Self Improvement 圖示。

其外觀如下 (請記得向下捲動):

bd178a52438cfcbc.png

讓我們看看 Toggle 上的變化版本,亦即 ToggleChip 可組合內容。

建立 ToggleChip 可組合內容

ToggleChip 的作用類似 Chip,但允許使用者透過圓形按鈕、切換元素或核取方塊互動。

ReusableComponents.kt 中搜尋「TODO: Create a ToggleChip」,並將目前的可組合方法替換為本程式碼。

步驟 6

// TODO: Create a ToggleChip Composable
@Composable
fun ToggleChipExample(modifier: Modifier = Modifier) {
    var checked by remember { mutableStateOf(true) }
    ToggleChip(
        modifier = modifier,
        checked = checked,
        toggleControl = {
            Icon(
                imageVector = ToggleChipDefaults.switchIcon(checked = checked),
                contentDescription = if (checked) "On" else "Off"
            )
        },
        onCheckedChange = {
            checked = it
        },
        label = {
            Text(
                text = "Sound",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    )
}

現在 ToggleChipExample() 可組合函式 (此程式碼所在函式) 可以透過切換元素 (而非核取方塊或圓形按鈕) 來產生 ToggleChip

首先,我們來建立 MutableState。我們主要是進行使用者介面示範,以便讓您查看 Wear 提供的功能,因此未在其他函式中執行此動作。

在一般應用程式中,您可能會想傳遞已勾選狀態和 lambda 來處理輕觸動作,因此可組合內容可能處於無狀態 (詳情請參閱這裡)。

針對本範例,我們只想輕鬆呈現 ToggleChip 的運作情況,藉由可正常運作的切換元素來呈現效果,即便我們沒有採取任何行動亦然。

接下來,我們會設定修飾符、已勾選狀態和切換圖示,以協助切換所需的功能。(本範例使用預設值。)

接著我們會建立 lambda 來變更狀態,最後再使用 Text 可組合內容以及一些基本參數來設定標籤。

其外觀如下:

452080e3dbb4f3f0.png

您現已看過許多 Wear OS 特定可組合項,如上文所述,大部分程式碼皆與您先前編寫的程式碼幾乎相同。

讓我們來看看一些更進階的資訊。

7. 遷移至 ScalingLazyColumn

您可能曾在行動應用程式中使用 LazyColumn 來產生垂直捲動清單。

由於圓形裝置的頂端和底部較小,因此可顯示項目的空間較少。基於以上原因,Wear OS 具有專屬的 LazyColumn 版本,以針對這些圓形裝置提供更妥善的支援。

ScalingLazyColumn 延伸 LazyColumn 以在螢幕頂端和底部支援縮放和透明度,讓使用者更容易讀取內容。

示範如下:

198ee8e8fa799f08.gif

請注意,當項目靠近中心時會放大至完整大小,然後在向外移動時會隨之縮小 (且會變得更為透明)。

以下是更具體的應用程式範例:

d6e02f406f96c664.gif

我們發現到這對可讀性而言非常實用。

您已瞭解到 ScalingLazyColumn 的實際運作,接下來讓我們開始轉換 LazyColumn

轉換為 ScalingLazyListState

MainActivity.kt 中搜尋「TODO: Swap to ScalingLazyListState」,然後將該留言和下一行替換為本程式碼。

步驟 7

// TODO: Swap to ScalingLazyListState
val listState = rememberScalingLazyListState()

這些名稱幾乎與「縮放」部分相同。就像 LazyListState 處理 LazyColumn 的狀態一樣,ScalingLazyListState 也會處理 ScalingLazyColumn 的狀態。

轉換為 ScalingLazyColumn

接著我們要替換為 ScalingLazyColumn

MainActivity.kt 中搜尋「TODO: Swap a ScalingLazyColumn」。首先,請將 LazyColumn 取代為 ScalingLazyColumn

然後一併移除 contentPaddingverticalArrangementScalingLazyColumn 已提供預設設定,並且能保證顯示更佳的預設視覺效果,因為大多數可視區域都會填滿清單項目。在大多數情況下,預設參數就足以應付;如果您在上方有標題,我們建議放進 ListHeader 中並列為第一個項目。否則,我們會建議您使用 itemIndexautoCentering 設為 0,這樣就能為第一個項目提供足夠的邊框間距。

步驟 8

// TODO: Swap a ScalingLazyColumn (Wear's version of LazyColumn)
ScalingLazyColumn(
    modifier = Modifier.fillMaxSize(),
    autoCentering = AutoCenteringParams(itemIndex = 0),
    state = listState

大功告成!其外觀如下:

442700f212089fd0.png

當您捲動時會於螢幕頂端與底部縮放內容和調整透明度,輕輕鬆鬆即可完成遷移!

當您上下移動冥想可組合內容時,就會確實留意到這點。

接著讓我們探討最後一個主題:Wear OS 的 Scaffold

8. 新增 Scaffold

Scaffold 提供版面配置結構,可協助您如同行動裝置般在一般模式下編排畫面,但有別於應用程式列、懸浮動作按鈕 (FAB)、導覽匣或其他行動裝置特定元素,其支援四種具有頂層元件的 Wear 特定版面配置:時間、暈影、捲動/位置指標,以及頁面指標。

此外還能處理圓形與非圓形裝置。

看起來像這樣:

TimeText

Vignette

PositionIndicator

PageIndicator

我們會詳細探討前三個元件,但先讓我們把 Scaffold 設定好。

新增 Scaffold

現在讓我們來新增 Scaffold 的樣板。

尋找「TODO (Start): Create a Scaffold (Wear Version)」,並在下方新增程式碼。

步驟 9

// TODO (Start): Create a Scaffold (Wear Version)
Scaffold(
    timeText = { },
    vignette = { },
    positionIndicator = { }
) {

我們將在後續步驟中依序說明每個參數。我們目前並未產生任何使用者介面。

接著,請務必在右方位置新增括弧。尋找「TODO (End): Create a Scaffold (Wear Version)」並加上括弧:

步驟 10

// TODO (End): Create a Scaffold (Wear Version)
}

請先執行。如下所示:

c2cb637a495bc977.png

請注意,自我們新增 Scaffold 後,其實際運作方式並無任何改變,但一旦開始導入元件後就會有所變化。

首先介紹三個參數中的第一個參數:TimeText

TimeText

TimeText 在背景中使用弧形文字,可讓開發人員輕鬆顯示時間而無需放置可組合項,也無須處理任何與時間相關的類別。

《材質指南》要求在以下位置顯示時間:任何重疊 (或應用程式) 體驗當中的任何螢幕頂端。實際範例如下:

d7a321e97b87b579.png

新增 TimeText 其實非常簡單。

尋找「timeText = { },」並替換為以下程式碼:

步驟 11

timeText = {
    if (!listState.isScrollInProgress) {
        TimeText()
    }
},

我們新增了額外的邏輯,以在使用者開始捲動時隱藏時間。

之後,我們會建立 TimeText 可組合內容。我們可以新增額外參數,以在時間的前後新增文字,但力求簡潔。

請試著執行。此時您應會看見時間,但只要捲動時間即會消失。

75c1964e19457962.png

接著來探討 Vignette

新增暈影

每當顯示可捲動畫面時,Vignette 會模糊處理穿戴式裝置螢幕的頂緣和底緣。

開發人員可以根據用途,指定模糊處理頂端、底部或此兩者。

範例如下:

b9b37010632bf52b.png

我們只有一個螢幕 (並且可捲動畫面),因此希望顯示「暈影」以方便閱讀。開始行動吧。

尋找「vignette = { },」並替換為以下程式碼:

步驟 12

vignette = {
    // Only show a Vignette for scrollable screens. This code lab only has one screen,
    // which is scrollable, so we show it all the time.
    Vignette(vignettePosition = VignettePosition.TopAndBottom)
},

參閱留言內容,進一步瞭解何時應該顯示暈影。針對本範例,我們想讓其一律顯示,並模糊處理畫面頂端和底部。

2c1ca979165bbe25.png

當您查看頂端或底部 (尤其是紫色可組合項) 時,應會看見效果。

讓我們完成 ScaffoldPositionIndicator 的最終參數。

新增 PositionIndicator

PositionIndicator (亦稱「捲動指標」) 是畫面右側的指標,可讓您根據傳遞的狀態物件類型,顯示目前的指標位置。在本範例中即是 ScalingLazyListState

範例如下:

b4b13badcfdc919e.png

您可能不瞭解為何位置指標必須提高至 Scaffold 層級,而非 ScalingLazyColumn 層級。

由於螢幕為曲面,因此位置指標必須處於智慧手錶中央 (Scaffold),而非處於可視區域的中央 (ScalingLazyColumn),否則可能會遭到截斷。

舉例來說,在以下的應用程式中,我們假設「播放清單」可組合內容不屬於可捲動區域。位置指標置中於 ScalingLazyColumn,並未佔滿整個螢幕畫面。因此大多數內容都遭到截斷。

f14296881a63650f.png

不過,如果我們改為將位置指標置中於整個可視介面 (透過 Scaffold 達成),您便可立即清楚看見該指標。

22dd9544d8dafcd5.png

這表示 PositionIndicator 要求 ScalingLazyListState (告知其在捲動清單中的位置) 高於 Scaffold

若您觀察力敏銳,可能會注意到我們已提升 ScalingLazyListStateScaffold 上方來隱藏或顯示時間,因此就本範例而言,我們的工作已完成。

我們現已說明位置指標應處於 Scaffold 的原因,接下來請將其新增至應用程式。

尋找「positionIndicator = { }」並替換為以下程式碼:

步驟 12

positionIndicator = {
    PositionIndicator(
        scalingLazyListState = listState
    )
}

此步驟相當簡易直覺,PositionIndicator 需要捲動狀態才能正確轉換顯示,而如今已不是問題!

另外還具備貼心功能,可在使用者未捲動時自行隱藏。

我們使用的是 ScalingLazyListState,但 PositionIndicator 採用其他捲動選項,例如 ScrollStateLazyListState,甚至還可處理旋轉側邊按鈕或

旋轉邊框。如要查看所有選項,請查看每個版本的 KDocs

現在外觀看起來會像這樣:

1b6fa8091b920587.png

請試著上下捲動。僅在捲動時才會看見捲動指標。

太棒了,您已完成大部分 Wear OS 可組合內容的使用者介面示範!

9. 恭喜

恭喜!您已瞭解關於在 Wear OS 上使用 Compose 的基本知識!

您現在可以重新應用所有 Compose 知識,創造精美的 Wear OS 應用程式!

後續步驟

查看其他 Wear OS 程式碼研究室:

其他資訊

意見回饋

我們很樂意傾聽您使用 Compose for Wear OS 的經驗,以及您由此所建構的內容!歡迎參與 Kotlin Slack #compose-wear 頻道的討論,並持續透過 Issue Tracker 提供意見回饋。

祝您一切順利!