So, I have followed many YouTube tutorials to correctly learn about Retrofit in Android and how to pass data from the response to my adapter and display the list but none of them is working for me right now and I don't know why.
In my MainActivity I am calling the RetrofitInstance and hence initiating a GET request to my API and fetching the response from it. When I debug my code and Log the response the body is correctly visible as it should be, but the problem occurs when I try to pass that very response in the form of list to my adapter.
Here's the code of both the files -
MainActivity code -
class QuizMainActivity : AppCompatActivity() {
private lateinit var quizCategoryAdapter: QuizCategoryAdapter
private lateinit var binding: ActivityQuizMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityQuizMainBinding.inflate(layoutInflater)
setContentView(binding.root)
hideactionbar()
setupRecyclerView()
lifecycleScope.launchWhenCreated {
val response = try{
RetrofitInstance.api.getQuizCategories()
}catch (e:IOException){
Log.d("QuizCatTag", "IOException"+e)
return@launchWhenCreated
}catch (e: HttpException){
Log.d("QuizCatTag", "HTTPException"+e)
return@launchWhenCreated
}
if(response.isSuccessful && response.body()!=null){
setupRecyclerView()
quizCategoryAdapter.quizCategoryList = response.body()!!.category_detail //place where I am sending my response list to my adapter.
Log.d("quizCategoryList", quizCategoryAdapter.quizCategoryList.toString() )
}else{
Log.d("TASG", "Response not successful")
}
}
}
private fun hideactionbar() {
supportActionBar?.hide()
}
private fun setupRecyclerView() = binding.quizCategoryRv.apply {
quizCategoryAdapter = QuizCategoryAdapter(this@QuizMainActivity)
adapter = quizCategoryAdapter
layoutManager = LinearLayoutManager(this@QuizMainActivity)
}
}
Adapter code - (I am also using DiffUtils in my adapter for handling the change in data)
class QuizCategoryAdapter(
private val context: Context
) : RecyclerView.Adapter<QuizCategoryAdapter.QuizCategoryHolder>() {
private val diffCallBack = object: DiffUtil.ItemCallback<CategoryDetail>(){
override fun areItemsTheSame(oldItem: CategoryDetail, newItem: CategoryDetail): Boolean {
return oldItem.category_name == newItem.category_name
}
override fun areContentsTheSame(oldItem: CategoryDetail, newItem: CategoryDetail): Boolean {
return oldItem == newItem
}
}
private val differ = AsyncListDiffer(this, diffCallBack)
var quizCategoryList : List<CategoryDetail>
get() = differ.currentList
set(value) {differ.submitList(value)}
val textList = quizCategoryList.chunked(3)
class QuizCategoryHolder(binding: QuizCategoryItemBinding) : RecyclerView.ViewHolder(binding.root){
val listTextV = listOf(binding.qciTv1, binding.qciTv2, binding.qciTv3)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuizCategoryAdapter.QuizCategoryHolder {
return QuizCategoryHolder(QuizCategoryItemBinding.inflate(LayoutInflater.from(context), parent,false))
}
override fun getItemCount(): Int {
return textList.size
}
override fun onBindViewHolder(holder: QuizCategoryHolder, position: Int) {
for (i in 0 until textList[position].size){
if(textList[position][i].category_name==""){
holder.listTextV[i].isVisible = false
}else{
holder.listTextV[i].text = textList[position][i].category_name
}
}
holder.itemView.setOnClickListener{
val intent = Intent(context, QuizQuestionActivity::class.java)
context.startActivity(intent)
}
}
}
I tried to display the list that I am fetching from API through Retrofit into my RecyclerView Adapter. But unfortunately, when I pass the list to my Adapter class it still shows as null/empty and does not display anything.
Having said that when I tried to pass the list as a parameter to class then it displayed the list. And in my opinion, I don't think that this is right way to do it.
Please guide me and let me know your thoughts. What is utmost correct way for achieving this?