Jetpack Compose Retrofit 多个 GET 查询,其中之一是可变的,并使用 Coil 显示照片

问题描述 投票:0回答:1

我正在关注 Google Android Developer Codelab,并且参与了一个名为“Bookshelf”的项目。主要思想是使用 Google API 来处理图书,以便:

  1. 检索书籍列表及其关联的 ID ( https://www.googleapis.com/books/v1/volumes?q=jazz+history )
{
  "kind": "books#volumes",
  "totalItems": 2542,
  "items": [
    {
      "kind": "books#volume",
      "id": "C1MI_4nZyD4C",
      "etag": "U0ZwtTrieGA",
      "selfLink": "https://www.googleapis.com/books/v1/volumes/C1MI_4nZyD4C",
      "volumeInfo": {
        "title": "The History of Jazz",
        "authors": [
          "Ted Gioia"
        ],
        "publisher": "Oxford University Press, USA",
        "publishedDate": "1997-11-20",
        "description": "Jazz is the most colorful and varied art form in the world and it was born in one of the most colorful and varied cities, New Orleans. From the seed first planted by slave dances held in Congo Square and nurtured by early ensembles led by Buddy Belden and Joe \"King\" Oliver, jazz began its long winding odyssey across America and around the world, giving flower to a thousand different forms--swing, bebop, cool jazz, jazz-rock fusion--and a thousand great musicians. Now, in The History of Jazz, Ted Gioia tells the story of this music as it has never been told before, in a book that brilliantly portrays the legendary jazz players, the breakthrough styles, and the world in which it evolved. Here are the giants of jazz and the great moments of jazz history--Jelly Roll Morton (\"the world's greatest hot tune writer\"), Louis Armstrong (whose O-keh recordings of the mid-1920s still stand as the most significant body of work that jazz has produced), Duke Ellington at the Cotton Club, cool jazz greats such as Gerry Mulligan, Stan Getz, and Lester Young, Charlie Parker's surgical precision of attack, Miles Davis's 1955 performance at the Newport Jazz Festival, Ornette Coleman's experiments with atonality, Pat Metheny's visionary extension of jazz-rock fusion, the contemporary sounds of Wynton Marsalis, and the post-modernists of the Knitting Factory. Gioia provides the reader with lively portraits of these and many other great musicians, intertwined with vibrant commentary on the music they created. Gioia also evokes the many worlds of jazz, taking the reader to the swamp lands of the Mississippi Delta, the bawdy houses of New Orleans, the rent parties of Harlem, the speakeasies of Chicago during the Jazz Age, the after hours spots of corrupt Kansas city, the Cotton Club, the Savoy, and the other locales where the history of jazz was made. And as he traces the spread of this protean form, Gioia provides much insight into the social context in which the music was born. He shows for instance how the development of technology helped promote the growth of jazz--how ragtime blossomed hand-in-hand with the spread of parlor and player pianos, and how jazz rode the growing popularity of the record industry in the 1920s. We also discover how bebop grew out of the racial unrest of the 1940s and '50s, when black players, no longer content with being \"entertainers,\" wanted to be recognized as practitioners of a serious musical form. Jazz is a chameleon art, delighting us with the ease and rapidity with which it changes colors. Now, in Ted Gioia's The History of Jazz, we have at last a book that captures all these colors on one glorious palate. Knowledgeable, vibrant, and comprehensive, it is among the small group of books that can truly be called classics of jazz literature.",
        "industryIdentifiers": [
          {
            "type": "ISBN_13",
            "identifier": "9780199840298"
          },
          {
            "type": "ISBN_10",
            "identifier": "0199840296"
          }
        ],
        "readingModes": {
          "text": true,
          "image": true
        },
        "pageCount": 481,
        "printType": "BOOK",
        "categories": [
          "Social Science"
        ],
        "maturityRating": "NOT_MATURE",
        "allowAnonLogging": false,
        "contentVersion": "1.2.2.0.preview.3",
        "panelizationSummary": {
          "containsEpubBubbles": false,
          "containsImageBubbles": false
        },
        "imageLinks": {
          "smallThumbnail": "http://books.google.com/books/content?id=C1MI_4nZyD4C&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
          "thumbnail": "http://books.google.com/books/content?id=C1MI_4nZyD4C&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
        },
        "language": "en",
        "previewLink": "http://books.google.ie/books?id=C1MI_4nZyD4C&printsec=frontcover&dq=jazz+history&hl=&cd=1&source=gbs_api",
        "infoLink": "http://books.google.ie/books?id=C1MI_4nZyD4C&dq=jazz+history&hl=&source=gbs_api",
        "canonicalVolumeLink": "https://books.google.com/books/about/The_History_of_Jazz.html?hl=&id=C1MI_4nZyD4C"
      },
      "saleInfo": {
        "country": "IE",
        "saleability": "NOT_FOR_SALE",
        "isEbook": false
      },
      "accessInfo": {
        "country": "IE",
        "viewability": "PARTIAL",
        "embeddable": true,
        "publicDomain": false,
        "textToSpeechPermission": "ALLOWED",
        "epub": {
          "isAvailable": true,
          "acsTokenLink": "http://books.google.ie/books/download/The_History_of_Jazz-sample-epub.acsm?id=C1MI_4nZyD4C&format=epub&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
        },
        "pdf": {
          "isAvailable": true,
          "acsTokenLink": "http://books.google.ie/books/download/The_History_of_Jazz-sample-pdf.acsm?id=C1MI_4nZyD4C&format=pdf&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
        },
        "webReaderLink": "http://play.google.com/books/reader?id=C1MI_4nZyD4C&hl=&source=gbs_api",
        "accessViewStatus": "SAMPLE",
        "quoteSharingAllowed": false
      },
      "searchInfo": {
        "textSnippet": "Now, in The History of Jazz, Ted Gioia tells the story of this music as it has never been told before, in a book that brilliantly portrays the legendary jazz players, the breakthrough styles, and the world in which it evolved."
      }
    },
[...]
}
  1. 使用图书 ID 执行第二次 GET 查询以检索其详细信息(示例:https://www.googleapis.com/books/v1/volumes/C1MI_4nZyD4C
{
  "kind": "books#volume",
  "id": "C1MI_4nZyD4C",
  "etag": "ljZDWl6LzoA",
  "selfLink": "https://www.googleapis.com/books/v1/volumes/C1MI_4nZyD4C",
  "volumeInfo": {
    "title": "The History of Jazz",
    "authors": [
      "Ted Gioia"
    ],
    "publisher": "Oxford University Press, USA",
    "publishedDate": "1997-11-20",
    "description": "Jazz is the most colorful and varied art form in the world and it was born in one of the most colorful and varied cities, New Orleans. From the seed first planted by slave dances held in Congo Square and nurtured by early ensembles led by Buddy Belden and Joe \"King\" Oliver, jazz began its long winding odyssey across America and around the world, giving flower to a thousand different forms--swing, bebop, cool jazz, jazz-rock fusion--and a thousand great musicians. Now, in The History of Jazz, Ted Gioia tells the story of this music as it has never been told before, in a book that brilliantly portrays the legendary jazz players, the breakthrough styles, and the world in which it evolved. Here are the giants of jazz and the great moments of jazz history--Jelly Roll Morton (\"the world's greatest hot tune writer\"), Louis Armstrong (whose O-keh recordings of the mid-1920s still stand as the most significant body of work that jazz has produced), Duke Ellington at the Cotton Club, cool jazz greats such as Gerry Mulligan, Stan Getz, and Lester Young, Charlie Parker's surgical precision of attack, Miles Davis's 1955 performance at the Newport Jazz Festival, Ornette Coleman's experiments with atonality, Pat Metheny's visionary extension of jazz-rock fusion, the contemporary sounds of Wynton Marsalis, and the post-modernists of the Knitting Factory. Gioia provides the reader with lively portraits of these and many other great musicians, intertwined with vibrant commentary on the music they created. Gioia also evokes the many worlds of jazz, taking the reader to the swamp lands of the Mississippi Delta, the bawdy houses of New Orleans, the rent parties of Harlem, the speakeasies of Chicago during the Jazz Age, the after hours spots of corrupt Kansas city, the Cotton Club, the Savoy, and the other locales where the history of jazz was made. And as he traces the spread of this protean form, Gioia provides much insight into the social context in which the music was born. He shows for instance how the development of technology helped promote the growth of jazz--how ragtime blossomed hand-in-hand with the spread of parlor and player pianos, and how jazz rode the growing popularity of the record industry in the 1920s. We also discover how bebop grew out of the racial unrest of the 1940s and '50s, when black players, no longer content with being \"entertainers,\" wanted to be recognized as practitioners of a serious musical form. Jazz is a chameleon art, delighting us with the ease and rapidity with which it changes colors. Now, in Ted Gioia's The History of Jazz, we have at last a book that captures all these colors on one glorious palate. Knowledgeable, vibrant, and comprehensive, it is among the small group of books that can truly be called classics of jazz literature.",
    "industryIdentifiers": [
      {
        "type": "ISBN_10",
        "identifier": "0199840296"
      },
      {
        "type": "ISBN_13",
        "identifier": "9780199840298"
      }
    ],
    "readingModes": {
      "text": true,
      "image": true
    },
    "pageCount": 480,
    "printedPageCount": 481,
    "printType": "BOOK",
    "categories": [
      "Social Science / Ethnic Studies / African American Studies",
      "History / United States / 20th Century"
    ],
    "maturityRating": "NOT_MATURE",
    "allowAnonLogging": false,
    "contentVersion": "1.2.2.0.preview.3",
    "panelizationSummary": {
      "containsEpubBubbles": false,
      "containsImageBubbles": false
    },
    "imageLinks": {
      "smallThumbnail": "http://books.google.com/books/content?id=C1MI_4nZyD4C&printsec=frontcover&img=1&zoom=5&edge=curl&imgtk=AFLRE730biSUWPH7wghApGEceQgvs4lpFCTDDGPT0dIp-EkMCBA1sLvNEGHhvoxr8_43Mtp-RTxRA-gZrTn1tc4rq9id-v8u7fvveuxUnrm3JfbRl-umhSHYDfo0S_PqhutDGS0mcpV1&source=gbs_api",
      "thumbnail": "http://books.google.com/books/content?id=C1MI_4nZyD4C&printsec=frontcover&img=1&zoom=1&edge=curl&imgtk=AFLRE70rZqUfLNXAlZ3Mp6KorU6BzZ2x_p528N9jzQZIV4WuRWVVJFT0A8SQy0WJBttQ3IWtTf6AoEW237Xu8O1vlNWxhibKUq4pt-ktxHLHieX-Y0lqoUgmMccjHtQSuvplVDtmBBGp&source=gbs_api",
      "small": "http://books.google.com/books/content?id=C1MI_4nZyD4C&printsec=frontcover&img=1&zoom=2&edge=curl&imgtk=AFLRE73RkCaP-LV0p65fciM3whXa6bbzVML38bukLHbCPhO6F2ecP6npI9UBmYw03reO6qT6NjAVLf9m8e788OLtrto-eGpGj2AZ9qPXlA7ja7Kffx0JbC_8v3gN7U-6Tfv_Jw5JM1FK&source=gbs_api",
      "medium": "http://books.google.com/books/content?id=C1MI_4nZyD4C&printsec=frontcover&img=1&zoom=3&edge=curl&imgtk=AFLRE70RBCOlwTFLS4ePUbKtMrE5P7UcdCedUtle3QhK5Q9UqgksVIHqiaqxkwxIsNFv1xKnd0xxsrOVaGhegawAmqqoGgbfdCl3hJZ9e6K6dM6aihXY16JEvsWAaQrBv6IXgfGtU2HG&source=gbs_api"
    },
    "language": "en",
    "previewLink": "http://books.google.ie/books?id=C1MI_4nZyD4C&hl=&source=gbs_api",
    "infoLink": "https://play.google.com/store/books/details?id=C1MI_4nZyD4C&source=gbs_api",
    "canonicalVolumeLink": "https://play.google.com/store/books/details?id=C1MI_4nZyD4C"
  },
  "layerInfo": {
    "layers": [
      {
        "layerId": "geo",
        "volumeAnnotationsVersion": "6"
      }
    ]
  },
  "saleInfo": {
    "country": "IE",
    "saleability": "NOT_FOR_SALE",
    "isEbook": false
  },
  "accessInfo": {
    "country": "IE",
    "viewability": "PARTIAL",
    "embeddable": true,
    "publicDomain": false,
    "textToSpeechPermission": "ALLOWED",
    "epub": {
      "isAvailable": true,
      "acsTokenLink": "http://books.google.ie/books/download/The_History_of_Jazz-sample-epub.acsm?id=C1MI_4nZyD4C&format=epub&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
    },
    "pdf": {
      "isAvailable": true,
      "acsTokenLink": "http://books.google.ie/books/download/The_History_of_Jazz-sample-pdf.acsm?id=C1MI_4nZyD4C&format=pdf&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
    },
    "webReaderLink": "http://play.google.com/books/reader?id=C1MI_4nZyD4C&hl=&source=gbs_api",
    "accessViewStatus": "SAMPLE",
    "quoteSharingAllowed": false
  }
}

应用程序应显示使用 Coil 从 API 异步获取的每本书的

thumbnail
对象中的
imageLinks
照片

我在做什么

我定义了以下Serialized数据类:

@Serializable
data class BookshelfBook(
    val items: List<Map<String, String>>
)
@Serializable
data class BookshelfVolume(
    val imageLinks: Map<String, String>
)

我正在尝试使用以下 API 接口获取数据

interface BookshelfApiService {
    @GET("?q=jazz+history")
    suspend fun getBooks(): List<BookshelfBook>

    @GET("{volume_id}")
    suspend fun getVolume(bookId: String): List<BookshelfVolume>
}

将它们全部放在以下存储库中:

interface BookshelfRepository {
    suspend fun getBookshelfBooks(): List<BookshelfBook>
    suspend fun getBookshelfVolumes(books: List<BookshelfBook>): List<BookshelfVolume>
}

class NetworkBookshelfRepository(
    private val bookshelfApiService: BookshelfApiService
) : BookshelfRepository {
    override suspend fun getBookshelfBooks(): List<BookshelfBook> =
        bookshelfApiService.getBooks()

    override suspend fun getBookshelfVolumes(books: List<BookshelfBook>): List<BookshelfVolume> =
ERROR --->        listOf(books.forEach { bookshelfApiService.getVolume(it["id"]) })
}

尝试在

BookshelfVolume
中构建
override suspend fun getBookShelfVolumes
列表时出现以下错误:

Type mismatch: inferred type is List<Unit> but List<BookshelfVolume> was expected

这些在 ViewModel 中使用:

package com.example.bookshelf.ui.model

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.bookshelf.BookshelfApplication
import com.example.bookshelf.data.BookshelfRepository
import com.example.bookshelf.network.BookshelfVolume
import kotlinx.coroutines.launch
import java.io.IOException

sealed interface BookshelfUiState {
    data class Success(val volumes: List<BookshelfVolume>): BookshelfUiState
    object Loading: BookshelfUiState
    object Error: BookshelfUiState
}

class BookshelfViewModel(
    private val bookshelfRepository: BookshelfRepository
) : ViewModel() {
    var bookshelfUiState: BookshelfUiState by mutableStateOf(BookshelfUiState.Loading)
        private set

    init {
        getBookshelfVolumes()
    }

    fun getBookshelfVolumes() {
        viewModelScope.launch {
            bookshelfUiState = try {
                val books = bookshelfRepository.getBookshelfBooks()
                BookshelfUiState.Success(bookshelfRepository.getBookshelfVolumes(books))
            } catch (e: IOException) {
                BookshelfUiState.Error
            }
        }
    }

    companion object {
        val Factory: ViewModelProvider.Factory = viewModelFactory {
            initializer {
                val application = (this[APPLICATION_KEY] as BookshelfApplication)
                val bookshelfRepository = application.container.bookshelfRepository
                BookshelfViewModel(bookshelfRepository = bookshelfRepository)
            }
        }
    }
}

因此,原则上:

  1. 获取书籍列表及其相关ID
  2. 对于给定 ID 的每本书,获取其详细信息并构建列表“缩略图”链接,以便将它们传递到 Coil

我被困住的地方

我不确定如何修复存储库,以便我可以为获取的每本书构建

BookshelfVolume
列表(
https://www.googleapis.com/books/v1/volumes?q=jazz+history
调用)

有关如何操作的任何提示

    对于使用
  1. @GET("{volume_id}")

    调用相同

    BookshelfApiService
     获取的书籍的每个 id 调用 
    getVolume(bookId: String)
     时,
    满足 
    @GET("?q=jazz+history")
     界面中的 
    BookshelfApiService

  2. 通过解析每本书获取的详细信息(卷)的“imageLinks”地图来构建“缩略图”链接列表

android retrofit2
1个回答
0
投票

通过以下方法解决了这个问题

BookshelfApiService.kt

package com.example.bookshelf.network

import retrofit2.http.GET
import retrofit2.http.Path

interface BookshelfApiService {
    @GET("?q=jazz+history")
    suspend fun getBooks(): List<BookshelfBook>

    @GET("{volume_id}")
    suspend fun getVolume(@Path("id") id: String): BookshelfVolume
}

书架Book.kt

package com.example.bookshelf.network

import kotlinx.serialization.Serializable

@Serializable
data class BookshelfBook(
    val id: String
)

书架卷.kt

package com.example.bookshelf.network

import kotlinx.serialization.Serializable

@Serializable
data class BookshelfVolume(
    val imageLinks: Map<String, String>
)

BookshelfRepository.kt

package com.example.bookshelf.data

import com.example.bookshelf.network.BookshelfApiService
import com.example.bookshelf.network.BookshelfBook
import com.example.bookshelf.network.BookshelfVolume

interface BookshelfRepository {
    suspend fun getBookshelfBooks(): List<BookshelfBook>
    suspend fun getBookshelfVolume(id: String): BookshelfVolume
}

class NetworkBookshelfRepository(
    private val bookshelfApiService: BookshelfApiService
) : BookshelfRepository {
    override suspend fun getBookshelfBooks(): List<BookshelfBook> =
        bookshelfApiService.getBooks()

    override suspend fun getBookshelfVolume(id: String): BookshelfVolume =
        bookshelfApiService.getVolume(id)
}

BookshelfViewModel.kt

package com.example.bookshelf.ui.model

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.bookshelf.BookshelfApplication
import com.example.bookshelf.data.BookshelfRepository
import com.example.bookshelf.network.BookshelfVolume
import kotlinx.coroutines.launch
import java.io.IOException

sealed interface BookshelfUiState {
    data class Success(val volumes: List<BookshelfVolume>): BookshelfUiState
    object Loading: BookshelfUiState
    object Error: BookshelfUiState
}

class BookshelfViewModel(
    private val bookshelfRepository: BookshelfRepository
) : ViewModel() {
    var bookshelfUiState: BookshelfUiState by mutableStateOf(BookshelfUiState.Loading)
        private set

    init {
        getBookshelfVolumes()
    }

    fun getBookshelfVolumes() {
        viewModelScope.launch {
            bookshelfUiState = try {
                val books = bookshelfRepository.getBookshelfBooks().map { it.id }
                val volumes = books.map { id ->
                    bookshelfRepository.getBookshelfVolume(id)
                }
                BookshelfUiState.Success(volumes)
            } catch (e: IOException) {
                BookshelfUiState.Error
            }
        }
    }

    companion object {
        val Factory: ViewModelProvider.Factory = viewModelFactory {
            initializer {
                val application = (this[APPLICATION_KEY] as BookshelfApplication)
                val bookshelfRepository = application.container.bookshelfRepository
                BookshelfViewModel(bookshelfRepository = bookshelfRepository)
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.