获取类型不匹配:推断类型为 List 但应为 Collection

Posted

技术标签:

【中文标题】获取类型不匹配:推断类型为 List 但应为 Collection【英文标题】:Getting type mismatch: inferred type is List but Collection was expected 【发布时间】:2021-09-26 03:37:05 【问题描述】:

仍然停留在这个 Breaking Bad API 应用程序上。 JSON 模型类是一个列表,但是当我在全局范围内调用响应并将其放入可变列表时,它会显示类型不匹配:推断的类型是 List 但 Collection 是预期的。我该如何解决它

主要活动

> class MainActivity : AppCompatActivity() 
> 
>     private lateinit var characterAdapter : MyAdapter
>     private var TAG = "MainActivity"
>     private var characterData= mutableListOf<ResponseBBItem>()
>     override fun onCreate(savedInstanceState: Bundle?) 
>         super.onCreate(savedInstanceState)
>         setContentView(R.layout.activity_main)
> 
>         characterAdapter = MyAdapter(characterData , this)
>         recyclerView.adapter = characterAdapter
>         val layoutMAnager = LinearLayoutManager(this)
>         recyclerView.layoutManager = layoutMAnager
>         getCharacterInfo()
> 
>         recyclerView.setOnClickListener 
>             getCharacterInfo()
>         
>     
> 
>     private fun getCharacterInfo() 
>         GlobalScope.launch(Dispatchers.IO) 
>             try 
>                 val response = Client.api.getInfo()
>                 if (response.isSuccessful) 
>                    val characterList = response.body()
>                     Log.d(TAG, characterData.toString())
>                     withContext(Dispatchers.Main) 
>                         if (characterList!= null) 
>                             Toast.makeText(this@MainActivity , "Data Loaded"

    enter code here

,Toast.LENGTH_SHORT).show()
>                             characterData.addAll(characterList.responseBB!!)
>                             characterAdapter.notifyDataSetChanged()
>                             tvText.text = characterList.toString()
>                         
>                     
>                 
>             
>             catch (e:Exception)
>                 withContext(Dispatchers.Main)
>                     Toast.makeText(applicationContext, "Cannot Load Data" , Toast.LENGTH_LONG).show()
>                 
>             
>         
>      

我在characterData.addAll(characterList.responseBB!!) 收到错误

API请求

interface APIRequest 

    @GET("character/random")

    suspend fun getInfo() : Response<ResponseBB>

响应BB

data class ResponseBB(

    @field:SerializedName("ResponseBB")
    val responseBB: List<ResponseBBItem?>? = null
)

我相信 List&lt;ResponseBBItem?&gt;? 中的 2 个 ?s 给了我错误

响应BBItem

data class ResponseBBItem(

    @field:SerializedName("birthday")
    val birthday: Any? = null,

    @field:SerializedName("img")
    val img: String? = null,

    @field:SerializedName("better_call_saul_appearance")
    val betterCallSaulAppearance: Any? = null,

    @field:SerializedName("occupation")
    val occupation: List<String?>? = null,

    @field:SerializedName("appearance")
    val appearance: List<Int?>? = null,

    @field:SerializedName("portrayed")
    val portrayed: String? = null,

    @field:SerializedName("name")
    val name: String? = null,

    @field:SerializedName("nickname")
    val nickname: String? = null,

    @field:SerializedName("char_id")
    val charId: Int? = null,

    @field:SerializedName("category")
    val category: String? = null,

    @field:SerializedName("status")
    val status: String? = null
)

客户

object Client 

    val gson = GsonBuilder().create()
    val retrofit = Retrofit.Builder()
        .baseUrl("https://www.breakingbadapi.com/api/")
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build()

    val  api = retrofit.create(APIRequest::class.java)

我的适配器

class MyAdapter(var listChar : List<ResponseBBItem?>, val context : Context) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() 
    class MyViewHolder(itemView : View): RecyclerView.ViewHolder(itemView) 
        var name = itemView.findViewById<TextView>(R.id.tvName)
        var occupation = itemView.findViewById<TextView>(R.id.tvOccupation)
        var protrayed = itemView.findViewById<TextView>(R.id.tvActor)
        var status = itemView.findViewById<TextView>(R.id.tvStatus)
        var appearance = itemView.findViewById<TextView>(R.id.tvAppearance)
        var image = itemView.findViewById<ImageView>(R.id.ivImage)
    

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder 
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item, parent , false)
        return MyViewHolder(view)
    

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) 
       holder.appearance.text = listChar[position]!!.appearance.toString()
        holder.name.text = listChar[position]!!.name
        holder.occupation.text = listChar[position]!!.occupation.toString()
        holder.protrayed.text = listChar[position]!!.portrayed
        holder.status.text = listChar[position]!!.status
        Picasso.get().load(listChar[position]!!.img).into(holder.image)
    

    override fun getItemCount() = listChar.size


【问题讨论】:

【参考方案1】:

问题是您试图将List&lt;ResponseBBItem?&gt; 放入MutableList&lt;ResponseBBItem&gt;。由于 MutableList 只能保存非空的 ResponseBBItem,因此它不会接受您的可为空的 ResponseBBItem 集合。要么将可变列表的类型更改为可为空,在传递给 addAll() 的列表上调用 filterNonNull(),或者将 reaponseBB 更改为返回 List&lt;ResponseBBItem&gt;

【讨论】:

如果我更改 ListAPI 调用不会运行。如何使可变列表可以为空? 你不想让 MutableList 可以为空,只有它里面的类型。你可以通过在类型后面加一个问号来做到这一点:private var characterData= mutableListOf&lt;ResponseBBItem?&gt;() 但是,这不太可能是你应该采取的解决方案,因为你必须处理列表中的空项目。最好的解决方案很可能是过滤掉空值:characterData.addAll(characterList.responseBB?.filterNotNull() ?: emptyList()) 顺便说一句,如果你刚开始使用 Kotlin,每次使用 !! 几乎肯定是错误的。完全适合使用它的情况非常有限,所以如果你想使用它,我建议你阅读更多关于可空性意味着什么的内容:kotlinlang.org/docs/null-safety.html Tenfour04 如果我执行 private var characterData= mutableListOf() 那么 API 不起作用 ???该属性与 API 无关。您必须定义“不起作用”。

以上是关于获取类型不匹配:推断类型为 List 但应为 Collection的主要内容,如果未能解决你的问题,请参考以下文章

Android Kotlin - viewBinding 类型不匹配:推断类型为 DrawerLayout 但应为 ConstraintLayout

错误:类型不匹配:推断类型是字符串?但布尔值是预期的

类型不匹配:推断类型为 Unit 但预期为 Boolean

kotlin gradle dsl问题:类型不匹配:推断类型是字符串但URI!预计

类型不匹配:推断的类型是 String 但在 kotlin 中需要 Charset

Kotlin:类型不匹配:推断类型是 Intent?但意图是预期的