I have implemented Result.Success and Result.Error in my ViewModel class but I am getting following error in my SecondActivity.kt C:\Users\Edgar\AndroidStudioProjects\GiphyAndroidApp\app\src\main\java\com\example\giphyandroidapp\ui\SecondActivity.kt: (52, 52): Type mismatch: inferred type is Result<List?> but List was expected
below my 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()
}
}
}
}
below 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)
}
below my ViewModel class where I have implemented Result.Success and Result.Error logic
@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()))
}
}
}
}
below Repository class
class GiphyTaskRepository
@Inject
constructor(private val giphyTaskApiService: GiphyTaskApiService)
{
suspend fun getGifsFromText(apikey:String,text:String,limit:Int)=
giphyTaskApiService.getGifsFromText(apikey,text,limit)
}
below my network interface
interface GiphyTaskApiService {
@GET("gifs/search")
suspend fun getGifsFromText(
@Query("api_key") api_key:String,
@Query("q") q:String ,
@Query("limit") limit:Int
):Response<GiphyResponse>
}
below 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
below Result class
sealed class Result<T>
data class Success<T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Any?>()
I want to know what I have to do in order to successfully implement result.success and result.error class and pass correct paremeter so that avoid mismatch error
I am getting following mismatch after implementing murat's answer
GiphyTaskAdapter expects List, but in ViewModel you have Result<List?>.
class GiphyTaskAdapter(val context: Context,val list:List<DataItem>)
var giphyresponse = MutableLiveData<Result<List<DataItem>?>>()
So, for example, you can change a type in ViewModel.
var giphyresponse: MutableLiveData<List<DataItem>> = MutableLiveData()
...
val list: List<DataItem> = response.body()?.data ?: emptyList()
giphyresponse.postValue(list)
UPD: sealed class can be handled as Marat wrote. Also, you should handle null type.
when(response) {
is Success -> {
val list: List<DataItem> = response.data ?: emptyList()
myadapter = GiphyTaskAdapter(this, list)
.......
}
is Error -> // Handle error case
}