无法从 API 获取商品详细信息

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

我正在使用 API 开发一个应用程序:https://gadhagod.github.io/Hyrule-Compendium-API/#/。一切正常,直到我尝试在单击列表中的项目时绘制项目细节。我没有很好地处理尝试访问项目属性的方式,但我不知道我到底哪里出了问题。我将详细介绍导航流程,但我不知道询问的内容是否太多

CompendiumApi

interface CompendiumApi {

    @GET("all?game=2")
    suspend fun getTearsAllEntries(): CompendiumList

    @GET("all?game=1")
    suspend fun getBreathAllEntries(): CompendiumList

    @GET("entry/{id}")
    suspend fun getItemInfo(
        @Path("id") id: Int
    ): Data
}

纲要存储库

@ActivityScoped
class CompendiumRepository @Inject constructor(
   private val api: CompendiumApi
){
   suspend fun getTearsAllEntries(): Resource<CompendiumList> {
      val response = try {
         api.getTearsAllEntries()
      } catch (e: Exception) {
         return Resource.Error("An unknown error occurred.")
      }
      return Resource.Success(response)
   }

   suspend fun getBreathAllEntries(): Resource<CompendiumList> {
      val response = try {
         api.getBreathAllEntries()
      } catch (e: Exception) {
         return Resource.Error("An unknown error occurred.")
      }
      return Resource.Success(response)
   }

   suspend fun getItemInfo(id: Int) : Resource<Data> {
      val response = try {
         Log.d("getItemInfo",api.getItemInfo(id).toString())
         api.getItemInfo(id)
      } catch (e: Exception) {
         return Resource.Error("An unknow error ocurred.")
      }
      return Resource.Success(response)
   }
}

CompendiumDetailViewModel

@HiltViewModel
class CompendiumDetailViewModel @Inject constructor(
   private val repository: CompendiumRepository
) : ViewModel() {

   suspend fun getItemInfo(id: Int): Resource<Data> {
      return repository.getItemInfo(id)
   }
}

概要详细信息屏幕

@Composable
fun CompendiumDetailCard(
   id: Int,
   viewModel: CompendiumDetailViewModel = hiltViewModel()
) {
   val itemInfo = produceState<Resource<Data>>(initialValue = Resource.Loading()) {
      value = viewModel.getItemInfo(id)
   }.value
   Log.d("itemDetailScreen", "item clicked: ${itemInfo.data.toString()}")
   ElevatedCard(
      elevation = CardDefaults.cardElevation(
         defaultElevation = 6.dp
      ),
      modifier = Modifier
         .fillMaxWidth()
   ) {
      ItemDetailStateWrapper(
         itemInfo = itemInfo,
         loadingModifier = Modifier
            .size(100.dp)
            .align(Alignment.CenterHorizontally)
            .padding(
               top = 16.dp,
               start = 16.dp,
               end = 16.dp,
               bottom = 16.dp
            )
      )
   }
}

@Composable
fun ItemDetailStateWrapper(
   itemInfo: Resource<Data>,
   loadingModifier: Modifier = Modifier
){
   when(itemInfo){
      is Resource.Success -> {
         ItemDetailInfo(
            itemInfo = itemInfo.data!!
         )
      }
      is Resource.Error -> {
         Text(
            text = itemInfo.message!!,
            color = Color.Red,
         )
      }
      is Resource.Loading -> {
         CircularProgressIndicator(
            color = MaterialTheme.colorScheme.primary,
            modifier = loadingModifier
         )
      }
   }
}

@Composable
fun ItemDetailInfo(
   itemInfo: Data
){
   Text(text = itemInfo.name ?: "No name") //"No name painted"
}

用于导航的MainActivity

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      window.statusBarColor = getColor(R.color.black)
      setContent {
         ZeldaCompendiumTheme {
            val navController = rememberNavController()
            NavHost(
               navController = navController,
               startDestination = "compendium_navigation"
            ) {
               composable("compendium_navigation") {
                  HomeContainer(navController = navController)
               }
               composable("compendium_tears_screen") {
                  TearsContainer(
                     navController = navController
                  )
               }
               composable("compendium_breath_screen") {
                  BreathContainer(
                     navController = navController
                  )
               }
               composable(
                  "item_detail_screen/{id}",
                  arguments = listOf(
                     navArgument("id") {
                        type = NavType.IntType
                     }
                  )
               ) {
                  val id = remember {
                     it.arguments?.getInt("id")
                  }
                  if (id != null) {
                     CompendiumDetailCard(
                        id = id,
                     )
                  }
               }
            }
         }
      }
   }
}

概要列表

data class CompendiumList(
   val data: List<Data>
)

纲要列表条目

data class CompendiumListEntry (
   val compendiumName: String,
   val category: String,
   val imageURL: String,
   val id: Int
)

数据

data class Data(
   val category: String,
   @SerializedName("common_location") val commonLocations: List<String>,
   @SerializedName("cooking_effect") val cookingEffect: String,
   val description: String,
   val dlc: Boolean,
   val drops: List<String>,
   val edible: Boolean,
   @SerializedName("fuse_attack_power") val fuseAttackPower: Int,
   @SerializedName("hearts_recovered")val heartsRecovered: Double,
   val id: Int,
   val image: String,
   val name: String,
   val properties: Properties
)

我必须说,通过控制台,我正在绘制与屏幕交互时发出的请求,并且当单击某个项目时,将通过控制台绘制所选项目的正确 URL:

android kotlin mvvm android-jetpack-compose
1个回答
0
投票

我认为 API 返回的 JSON 结构与您想要将 JSON 解析成的数据类结构之间存在简单的不匹配。

您将需要引入新的数据类或更新您的

CompendiumListItem
类,如下所示:

data class CompendiumListEntry (
   val data: Data
)

然后将此数据类设置为您的

getItemInfo
API 函数的类型:

@GET("entry/{id}")
suspend fun getItemInfo(
    @Path("id") id: Int
): CompendiumListEntry

相应地更新对该函数的所有调用:

suspend fun getItemInfo(id: Int) : Resource<CompendiumListEntry> {
    val response = try {
       Log.d("getItemInfo",api.getItemInfo(id).toString())
       api.getItemInfo(id)
    } catch (e: Exception) {
       return Resource.Error("An unknow error ocurred.")
    }
    return Resource.Success(response)
}

在您的可组合项中,您可能必须这样做(我不知道您的资源类是如何实现的):

val itemInfo = produceState<Resource<Data>>(initialValue = Resource.Loading()) {
    value = viewModel.getItemInfo(id)
}.value
Log.d("itemDetailScreen", "item clicked: ${itemInfo.data.data.toString()}")
© www.soinside.com 2019 - 2024. All rights reserved.