Reputation: 11
I have tried displaying the items from this API
https://www.themealdb.com/api/json/v1/1/categories.php
upon doing logcat all the conditions are true and valid , all the respective adapters are calling but items are not displaying in recyclerview
I have given the intenet permission, and added suitable dependecies of coroutines, retrofit, picasso for displaying the image
What could be the possible issue and how to resolve it, Any help will be much appreciated
This is my HomeFragment file
import retrofit2.HttpException
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.ambrosia.Adaptors.catAdap
import com.example.ambrosia.RetroInstance
import com.example.ambrosia.databinding.FragmentHomeBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private lateinit var myAdapter: catAdap
private lateinit var rv :RecyclerView
private val job = Job()
private val coroutineScope = CoroutineScope(Dispatchers.Main + job)
private var isDataLoaded = false // Track if data has been loaded
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rv = binding.rvCategory
rv.layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
myAdapter = catAdap(this@HomeFragment, emptyList())
rv.adapter = myAdapter
if (!isDataLoaded){
Log.d("homefragment", "onViewCreated: fetchcategories called sucessfully")
fetchCategories()
}
}
private fun fetchCategories() {
coroutineScope.launch {
val response = try {
RetroInstance.api.getCategory()
} catch (e: HttpException) {
Log.e("HomeFragment", "Http Error: ${e.message}", e)
withContext(Dispatchers.Main) {
Toast.makeText(requireContext(), "Network Error", Toast.LENGTH_SHORT).show()
}
return@launch
} catch (e: IOException) {
Log.e("HomeFragment", "I/O Error: ${e.message}", e)
withContext(Dispatchers.Main) {
Toast.makeText(requireContext(), "Network Error", Toast.LENGTH_SHORT).show()
}
return@launch
} catch (e: Exception) {
Log.e("HomeFragment", "Generic Error: ${e.message}", e)
withContext(Dispatchers.Main) {
Toast.makeText(requireContext(), "An Error Occured", Toast.LENGTH_SHORT).show()
}
return@launch
}
withContext(Dispatchers.Main) {
if (response.categories.isNotEmpty()) {
Log.d("HomeFragment", "Category list size: ${response.categories.size}")
myAdapter.catlist = response.categories
Log.d("HomeFragment", "after cat;ist called line 2")
myAdapter.notifyDataSetChanged()
Log.d("HomeFragment", "after notifydtasetchange")
myAdapter.onItemClick = { category ->
// Handle item click here
Log.d("HomeFragment", "Clicked on category: ${category.strCategory}")
}
} else {
Log.w("HomeFragment", "Category list is empty")
Toast.makeText(requireContext(), "No Categories Found", Toast.LENGTH_SHORT).show()
}
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
job.cancel()
}
}
This is my Adapter for the recyclerview
package com.example.ambrosia.Adaptors
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.example.ambrosia.Models.Category
import com.example.ambrosia.R
import com.squareup.picasso.Picasso
class catAdap(val context: Fragment, var catlist: List<Category>) :
RecyclerView.Adapter<catAdap.MyViewHolder>(){
lateinit var onItemClick: ((Category) -> Unit)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(context.requireContext())
.inflate(R.layout.itemdefine, parent, false) // Inflate your item layout
return MyViewHolder(itemView)
}
override fun getItemCount(): Int {
return catlist.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem =catlist[position]
Log.d("TAG", "onBindViewHolder: item displayed succesfully")
Picasso.get()
.load(currentItem.strCategoryThumb)
.into(holder.img)
Log.d("TAG", "onBindViewHolder: item displayed after picasso")
holder.itemView.setOnClickListener {
onItemClick.invoke(currentItem)
}
}
class MyViewHolder (itemView: View) : RecyclerView.ViewHolder(itemView) {
val img :ImageView
init {
img = itemView.findViewById(R.id.rvImg)
}
}
}
Upvotes: 1
Views: 22
Reputation: 3098
Modify the fetchCategory
function in HomeFragment
withContext(Dispatchers.Main) {
if (response.categories.isNotEmpty()) {
Log.d("HomeFragment", "Category list size: ${response.categories.size}")
myAdapter.catlist = response.categories
myAdapter.notifyDataSetChanged() // Notifying the adapter about dataset change
myAdapter.onItemClick = { category ->
Log.d("HomeFragment", "Clicked on category: ${category.strCategory}")
}
} else {
Log.w("HomeFragment", "Category list is empty")
Toast.makeText(requireContext(), "No Categories Found", Toast.LENGTH_SHORT).show()
}
}
Update Constructor parameter's AccessModifier in adapter catAdap
class catAdap(val context: Fragment, private var catlist: List<Category>) :
Add following method in your adapter catAdap
fun updateList(newList: List<Category>) {
catlist = newList
notifyDataSetChanged()
}
Now, from fragment, update your list like below:
myAdapter.updateList(response.categories)
Upvotes: 0