Android Compose UI 圖片與資源載入

在 Compose 中顯示圖片,我們使用 Image Composable。

顯示本地資源 (Drawable)

向量圖 (Vector Drawable)

推薦優先使用向量圖(如 Material Icons),因為它們體積小且縮放不失真。

Image(
    imageVector = Icons.Filled.Home, // 使用內建圖標
    contentDescription = "Home Icon", // 無障礙描述 (必填,或是 null)
    colorFilter = ColorFilter.tint(Color.Blue) // 著色
)

點陣圖 (Raster Images - PNG/JPG)

Image(
    painter = painterResource(id = R.drawable.my_photo),
    contentDescription = null,
    contentScale = ContentScale.Crop, // 裁剪模式
    modifier = Modifier.size(100.dp).clip(CircleShape) // 圓形頭像
)

ContentScale 常見選項:

  • Crop:填滿並裁剪多餘部分 (CenterCrop)。
  • Fit:完整顯示,可能有留白 (FitCenter)。
  • FillBounds:拉伸填滿。

載入網路圖片 (Coil)

Compose 團隊官方推薦使用 Coil (Coroutine Image Loader) 來載入網路圖片。它完全用 Kotlin Coroutines 寫成,輕量且效能佳。

安裝 Coil

libs.versions.tomlbuild.gradle.kts 加入: implementation("io.coil-kt:coil-compose:2.x.x")

基本用法 (AsyncImage)

Coil 提供了 AsyncImage Composable,使用起來非常簡單:

AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = null,
    modifier = Modifier.size(150.dp),
    placeholder = painterResource(R.drawable.loading), // 載入中顯示
    error = painterResource(R.drawable.error) // 錯誤時顯示
)

進階用法 (SubcomposeAsyncImage)

如果你需要更細緻的控制(例如在載入時顯示一個轉圈圈動畫),可以使用 SubcomposeAsyncImage

SubcomposeAsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = null,
) {
    val state = painter.state
    if (state is AsyncImagePainter.State.Loading || state is AsyncImagePainter.State.Error) {
        CircularProgressIndicator() // 顯示進度條
    } else {
        SubcomposeAsyncImageContent() // 顯示圖片
    }
}

圖片效能優化

  • 預先載入:如果你知道使用者即將看到某張大圖,可以使用 Coil 的 imageLoader.enqueue 預先載入。
  • 適當大小:載入網路圖片時,Server 端最好能提供適當解析度的縮圖,避免在手機上下載 4K 原圖只為了顯示一個小頭像。
  • 快取:Coil 預設會處理記憶體與磁碟快取,通常不需要額外設定。

小結

  • 本地小圖示用 Icon + ImageVector
  • 本地照片用 Image + painterResource
  • 網路圖片首選 CoilAsyncImage