iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
Mobile Development

Jetpack Compose 從心開始系列 第 18

Jetpack Compose 從心開始 Day18 - 載入並顯示網際網路上的圖片

  • 分享至 

  • xImage
  •  

前言

   從網際網路取得資料後,JSON 內有圖片的url,那我們就來看看如何顯示圖片吧 

Compose 使用 Coil 顯示下載的圖片

什麼是 Coil?

Coil 是一個 Android 圖片載入庫,專為 Jetpack Compose 設計,提供高效、可擴展且易於使用的圖片載入功能。它能夠從網路、資產、位元組陣列等多種來源載入圖片,並提供豐富的配置選項。

為什麼選擇 Coil?

  • 與 Compose 完美整合: Coil 專為 Compose 設計,可以直接在 Compose 組合中使用,無需額外的適配器。
  • 高性能: Coil 採用了許多優化技術,如記憶體緩存、磁碟緩存、多線程下載等,以提供快速的圖片載入體驗。
  • 可擴展性: Coil 提供了豐富的 API,可以自定義圖片處理、錯誤處理、過渡動畫等。
  • 易用性: Coil 的 API 簡單易用,只需提供圖片 URL 或其他資料來源即可。

新增 Coil 依附元件

在你的 build.gradle 檔案中添加 Coil 的程式庫

// Coil
implementation("io.coil-kt:coil-compose:2.4.0")

在 Compose 中使用 AsyncImage 可組合函式

AsyncImage 支援與標準 Image 可組合函式相同的引數。此外,該函式也支援設定 placeholder/error/fallback 繪圖工具和 onLoading/onSuccess/onError 回呼。

import androidx.compose.ui.layout.ContentScale

@Composable
fun MarsPhotoCard(photo: MarsPhoto, modifier: Modifier = Modifier) {
   AsyncImage(
       model = ImageRequest.Builder(context = LocalContext.current)
           .data(photo.imgSrc)
           .crossfade(true)
           .build(),
       contentDescription = stringResource(R.string.mars_photo),
       contentScale = ContentScale.Crop,
       modifier = modifier,
   )
}

Compose 透過 LazyVerticalGrid 顯示圖片格線

LazyVerticalGrid 是 Jetpack Compose 提供的一個可滾動的垂直網格佈局,非常適合用來顯示大量圖片。它可以根據內容動態調整高度,並且在滾動時高效地載入和顯示項目。

@Composable
fun PhotosGridScreen(
    photos: List<MarsPhoto>,
    modifier: Modifier = Modifier,
    contentPadding: PaddingValues = PaddingValues(0.dp),
) {
    LazyVerticalGrid(
        columns = GridCells.Adaptive(150.dp),
        modifier = modifier.padding(horizontal = 4.dp),
        contentPadding = contentPadding,
    ) {
        items(items = photos, key = { photo -> photo.id }) { photo ->
            MarsPhotoCard(
            photo,
            modifier = modifier
                .padding(4.dp)
                .fillMaxWidth()
                .aspectRatio(1.5f)
        )
        }
    }
}
修改一下 MarsPhotoCard
@Composable
fun MarsPhotoCard(photo: MarsPhoto, modifier: Modifier = Modifier) {

    Card(
        modifier = modifier,
        elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
    ) {

        AsyncImage(
            model = ImageRequest.Builder(context = LocalContext.current)
                .data(photo.imgSrc)
                .crossfade(true)
                .build(),
            error = painterResource(R.drawable.ic_broken_image),
            placeholder = painterResource(R.drawable.loading_img),
            contentDescription = stringResource(R.string.mars_photo),
            contentScale = ContentScale.Crop,
            modifier = Modifier.fillMaxWidth()
        )
    }
}

執行結果

https://ithelp.ithome.com.tw/upload/images/20240928/20121643IPM7ETHFdZ.png

更新 ViewModel 測試

@Test
    fun marsViewModel_getMarsPhotos_verifyMarsUiStateSuccess() =
        runTest {
            val marsViewModel = MarsViewModel(
                marsPhotosRepository = FakeNetworkMarsPhotosRepository()
            )
            assertEquals(
                MarsUiState.Success(FakeDataSource.photosList),
                marsViewModel.marsUiState
            )
        }

執行測試結果

https://ithelp.ithome.com.tw/upload/images/20240928/201216437fTItANbEF.png

參考

https://developer.android.com/codelabs/basic-android-kotlin-compose-load-images?hl=zh-tw#0


上一篇
Jetpack Compose 從心開始 Day17 -從網際網路取得資料
下一篇
Jetpack Compose 從心開始 Day19 - 使用 SQL 讀取資料庫並在其中寫入資料
系列文
Jetpack Compose 從心開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言