Несоответствие типа: предполагаемый тип: Result ‹List ‹DataItem›?› Но List ‹DataItem› ожидался

Я реализовал Result.Success и Result.Error в моем классе ViewModel, но я получаю следующую ошибку в моем SecondActivity.kt C: \ Users \ Edgar \ AndroidStudioProjects \ GiphyAndroidApp \ app \ src \ main \ java \ com \ example \ giphyandroidapp \ ui \ SecondActivity.kt: (52, 52): Несоответствие типов: предполагаемый тип - Result ‹List?›, но 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, где я реализовал логику 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 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

ниже класса результата

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 и передать правильный параметр, чтобы избежать ошибки несоответствия

Я получаю несоответствие после выполнения ответа Мурата

ошибка несоответствия


person Community    schedule 26.06.2021    source источник


Ответы (2)


GiphyTaskAdapter ожидает List, но в ViewModel у вас есть Result ‹List?›.

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)

UPD: с запечатанным классом можно обращаться, как писал Марат. Кроме того, вы должны обрабатывать нулевой тип.

when(response) {
    is Success -> {
        val list: List<DataItem> = response.data ?: emptyList()
        myadapter = GiphyTaskAdapter(this, list)
        
        .......
    }
    is Error -> // Handle error case
}
person Runny    schedule 26.06.2021
comment
если я собираюсь изменить, я не могу реализовать логику result.success и result.error - person ; 26.06.2021
comment
ваш ответ неверен, пожалуйста, не отвечайте, если вы не можете понять мою проблему - person ; 26.06.2021
comment
Таким образом, вы можете перефразировать свою проблему и удалить ненужную информацию, чтобы она была более понятной. Если проблема в обработке запечатанных классов, то Марат правильно ответил, как с этим можно справиться. - person Runny; 26.06.2021
comment
уже воспроизвести ответ марата, не распознав response.data - person ; 26.06.2021
comment
в этой строке я получаю сообщение об ошибке myadapter = GiphyTaskAdapter (this, response? .data) response.data type mismatch. Требуется: Список ‹DataItem› Найдено: Список ‹DataItem›? - person ; 26.06.2021
comment
Итак, вам нужен тип, не допускающий значения NULL, и вы помещаете тип, допускающий значение NULL. Просто как-нибудь обработайте null. Т.е. response.data?.let {GiphyTaskAdapter (это, оно)} - person Runny; 26.06.2021
comment
Несовместимые типы: Ошибка и результат ‹Список ‹DataItem›?›! - person ; 26.06.2021
comment
как насчет ошибки - person ; 26.06.2021
comment
Почему здесь тип ошибки? Вы помещали его в ветку Ошибка? - person Runny; 26.06.2021
comment
Ранни большое спасибо за твой ответ - person ; 26.06.2021
comment
Позвольте нам продолжить это обсуждение в чате. - person ; 27.06.2021

Обновлено

Вам нужно проверить свой response, успешно он или нет. Что-то вроде:

when(response) {
    is Success -> {
        myadapter = GiphyTaskAdapter(this, response.data)
        .......
    }
    is Error -> // Handle error case
}
person Marat    schedule 26.06.2021
comment
Можете ли вы помочь мне написать логику SecondActivity.kt, потому что я получаю сообщение об ошибке в viewModel.giphyresponse.observe (this, {response - - person ; 26.06.2021
comment
? ваш ответ неверный - person ; 26.06.2021
comment
Что за ошибка? - person Marat; 26.06.2021
comment
Вы его импортировали? Это код, который вы можете поместить в SecondActivity - person Marat; 26.06.2021
comment
Неразрешенная ссылка: Успех - person ; 26.06.2021
comment
да, я поставил, как вы мне сказали - person ; 26.06.2021
comment
может мне нужно обновить мою вторую активность - person ; 26.06.2021
comment
Тогда вы можете попробовать просто is Success -> без Result - person Marat; 26.06.2021
comment
Marat result.data также выдает ошибку - person ; 26.06.2021
comment
Где вы видите result.data? Пожалуйста, измените код так, как вам нужно. Я только что показал вам, как обращаться с Result классом в целом - person Marat; 26.06.2021
comment
Я получаю сообщение об ошибке myadapter = GiphyTaskAdapter (this, response.data) respnse.data // строка данных с красной ошибкой - person ; 26.06.2021
comment
Неразрешенная ссылка: данные - person ; 26.06.2021
comment
что вы предлагаете - person ; 26.06.2021
comment
Какая у вас ошибка? - person Marat; 26.06.2021
comment
Несоответствие типов. Требуется: Список ‹DataItem› Найдено: Список ‹DataItem›? - person ; 26.06.2021
comment
пожалуйста, проверьте мое второе действие обновления - person ; 26.06.2021