类型不匹配:推断类型为 Result<List<DataItem>?> 但预期为 List<DataItem>

Type mismatch: inferred type is Result<List<DataItem>?> but List<DataItem> was expected

我已经在我的 ViewModel class 中实现了 Result.Success 和 Result.Error,但是我在 SecondActivity.kt C:\Users\Edgar\AndroidStudioProjects\GiphyAndroidApp\app\src\main\java\com\example\giphyandroidapp\ui\SecondActivity.kt 中遇到了以下错误: (52, 52): 类型不匹配:推断类型为 Result 但预期为 List

低于我的SecondActivity.kt

  package com.example.giphyandroidapp.ui
import com.example.giphyandroidapp.utils.Result
import com.example.giphyandroidapp.utils.Error
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Toast
import com.example.giphyandroidapp.utils.Constants
import com.example.giphyandroidapp.viewmodel.GiphyTaskViewModel
import com.example.giphyandroidapp.adapters.GiphyTaskAdapter

import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import com.example.giphyandroidapp.databinding.ActivitySecondBinding
import com.example.giphyandroidapp.utils.Success
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class SecondActivity : AppCompatActivity() ,View.OnClickListener {

    lateinit var binding: ActivitySecondBinding
    val viewModel: GiphyTaskViewModel by viewModels()

    var text: String = ""
    lateinit var myadapter: GiphyTaskAdapter


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivitySecondBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val intent = intent
        if (intent.hasExtra("text")) {
            // list= intent.getParcelableArrayListExtra<Parcelable>("response")!! as List<DataItem>
            text = intent.getStringExtra("text").toString()

            if (text != null) {
                bindData()
            }
        }

        binding.getresultbtn.setOnClickListener(this)
    }

    private fun bindData() {

        viewModel.getGifsFromText(Constants.Api_Key, text, Constants.Limit)

        viewModel.giphyresponse.observe(this,
            { response ->


                when (response) {
                     is Success -> {
                        myadapter = GiphyTaskAdapter(this, response.data)
                    }
                     is  Error -> {

                    } // Handle error case
                }


                binding.imgsrecycler.apply {
                    adapter = myadapter
                    layoutManager = GridLayoutManager(this@SecondActivity, 2)
                    visibility = View.VISIBLE
                }
                binding.progressBar.visibility = View.GONE
            })
        }




    override fun onClick(v: View?) {
        var mytext: String = ""
        mytext = binding.txtword.text.toString()

        if (mytext.equals("")) {
            Toast.makeText(this, "you must enter word", Toast.LENGTH_LONG).show()
        } else {


            if (text.equals(mytext)) {
                val builder = android.app.AlertDialog.Builder(this)
                builder.setTitle("Winner")
                builder.setMessage("Excellent , you win \n Play game again ?!")
                builder.setPositiveButton("Yes") { dialog, which ->
                    startActivity(Intent(this, MainActivity::class.java))
                }
                builder.setNegativeButton("No") { dialog, which ->
                    dialog.dismiss()
                }
                builder.create().show()

            } else {

                val builder = android.app.AlertDialog.Builder(this)
                builder.setTitle("Loser")
                builder.setMessage("fail , you lose \n Game over ! \n Play game again ?!")
                builder.setPositiveButton("Yes") { dialog, which ->
                    startActivity(Intent(this, MainActivity::class.java))
                }
                builder.setNegativeButton("No") { dialog, which ->
                    dialog.dismiss()
                }
                builder.create().show()

            }

        }
    }
}

低于GiphyAdapter.kt

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.example.giphyandroidapp.databinding.ListItemBinding
import com.example.giphyandroidapp.model.gifsresponse.DataItem
import com.example.giphyandroidapp.model.gifsresponse.Images
import com.example.giphyandroidapp.utils.Result

class GiphyTaskAdapter(val context: Context,val list:List<DataItem>) : RecyclerView.Adapter<GiphyTaskAdapter.GiphyTaskViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GiphyTaskAdapter.GiphyTaskViewHolder {
        return GiphyTaskViewHolder(ListItemBinding.inflate(LayoutInflater.from(parent.context),parent,false))
    }

    override fun onBindViewHolder(holder: GiphyTaskAdapter.GiphyTaskViewHolder, position: Int) {
        var item:DataItem = list.get(position)
        var imageitem: Images =item.images
        holder.binding.apply {
            img.load(imageitem.original.url){
                crossfade(true)
                crossfade(1000)
            }
        }

        holder.itemView.setOnClickListener {mview->

        }
    }

    override fun getItemCount()=list.size

    inner class GiphyTaskViewHolder(val binding: ListItemBinding):
        RecyclerView.ViewHolder(binding.root)
}

在我的 ViewModel class 下面,我已经实现了 Result.Success 和 Result.Error 逻辑

@HiltViewModel
class GiphyTaskViewModel
@Inject
constructor(private val giphyTaskRepository: GiphyTaskRepository):ViewModel()
{
    var giphyresponse = MutableLiveData<Result<List<DataItem>?>>()



    fun getGifsFromText(apikey:String,text:String,limit:Int)= viewModelScope.launch {
    giphyTaskRepository.getGifsFromText(apikey,text,limit).let { response->
        if(response?.isSuccessful){
            var list=response.body()?.data
            giphyresponse.postValue(Success(list))
        }else{
            Error(Exception(response.message()))

        }

    }
}

}

存储库下方 class

class GiphyTaskRepository
@Inject
constructor(private val giphyTaskApiService: GiphyTaskApiService)
{

    suspend fun getGifsFromText(apikey:String,text:String,limit:Int)=
        giphyTaskApiService.getGifsFromText(apikey,text,limit)
}

在我的网络接口下面

interface GiphyTaskApiService {

    @GET("gifs/search")
    suspend fun getGifsFromText(
        @Query("api_key") api_key:String,
        @Query("q") q:String ,
        @Query("limit") limit:Int
    ):Response<GiphyResponse>
}

低于GiphyResponse.kt

@Parcelize
data class GiphyResponse(

    @field:SerializedName("pagination")
    val pagination: Pagination,

    @field:SerializedName("data")
    val data: List<DataItem>,

    @field:SerializedName("meta")
    val meta: Meta
) : Parcelable

低于结果 class

sealed class Result<T>
data class Success<T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Any?>()

我想知道我必须做什么才能成功实施 result.success 和 result.error class 并传递正确的参数以避免不匹配错误

我在实施 murat 的回答后遇到以下不匹配问题

已更新

您需要检查您的 response 是否成功。类似于:

when(response) {
    is Success -> {
        myadapter = GiphyTaskAdapter(this, response.data)
        .......
    }
    is Error -> // Handle error case
}

GiphyTaskAdapter 需要 List,但在 ViewModel 中你有 Result

class GiphyTaskAdapter(val context: Context,val list:List<DataItem>)
var giphyresponse = MutableLiveData<Result<List<DataItem>?>>()

因此,例如,您可以更改 ViewModel 中的类型。

var giphyresponse: MutableLiveData<List<DataItem>> = MutableLiveData()
...
val list: List<DataItem> = response.body()?.data ?: emptyList()
giphyresponse.postValue(list)

更新: sealed class 可以像马拉写的那样处理。另外,你应该处理空类型。

when(response) {
    is Success -> {
        val list: List<DataItem> = response.data ?: emptyList()
        myadapter = GiphyTaskAdapter(this, list)
        
        .......
    }
    is Error -> // Handle error case
}