I'm trying to figure out on what to do as my recyclerview seems to be not working. I'm still fairly new to mobile development so I'm not exactly sure I'm gonna do. There was no error/warning messages in the logs regarding recyclerview and it still was able to run the build however my only issue is the said recyclerview not being visible.
At first I thought it was because there was no data yet as when I dragged the recyclerview to the component tree, it was supposed to show a preview of items 0-9 in the design mode even though there was no data as from what I've observed watching videos that discuss about recyclerview. Then I did the backend of the activity I was working on and have my firebase connected to it but still, the recyclerview is not showing.
Here is my code:
MainActivity.kt
package com.example.dashboard.Activity
import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.dashboard.Activity.BaseActivity
import com.example.dashboard.Adapter.CategoryAdapter
import com.example.dashboard.R
import com.example.dashboard.ViewModel.MainViewModel
import com.example.dashboard.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val viewModel = MainViewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initCategory()
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
private fun initCategory() {
binding.progressBarCategory.visibility = View.VISIBLE
viewModel.category.observe(this, Observer{
binding.viewCategory.layoutManager = LinearLayoutManager(this@MainActivity,
LinearLayoutManager.HORIZONTAL,false)
binding.viewCategory.adapter= CategoryAdapter(it)
binding.progressBarCategory.visibility= View.GONE
})
viewModel.loadCategory()
}
}
CategoryAdapter.kt
package com.example.dashboard.Adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.dashboard.Domain.CategoryModel
import com.example.dashboard.databinding.ViewholderCategoryBinding
class CategoryAdapter(val items: MutableList<CategoryModel>):
RecyclerView.Adapter<CategoryAdapter.Viewholder>() {
private lateinit var context: Context
inner class Viewholder(val binding: ViewholderCategoryBinding): RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryAdapter.Viewholder {
context=parent.context
val binding=ViewholderCategoryBinding.inflate(LayoutInflater.from(context),parent,false)
return Viewholder(binding)
}
override fun onBindViewHolder(holder: CategoryAdapter.Viewholder, position: Int) {
val item=items[position]
holder.binding.titleText.text=item.Name
Glide.with(context)
.load(item.Picture)
.into(holder.binding.img)
}
override fun getItemCount(): Int =items.size
}
CategoryModel.kt
package com.example.dashboard.Domain
data class CategoryModel(
val Id:Int=0,
val Name: String="",
val Picture: String=""
)
MainViewModel.kt
package com.example.dashboard.ViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.dashboard.Domain.CategoryModel
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener
class MainViewModel() : ViewModel() {
private val firebaseDatabase = FirebaseDatabase.getInstance()
private val _category = MutableLiveData<MutableList<CategoryModel>>()
val category: LiveData<MutableList<CategoryModel>> = _category
fun loadCategory(){
val ref=firebaseDatabase.getReference("Category")
ref.addValueEventListener(object :ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
val lists = mutableListOf<CategoryModel>()
for (childSnapshot in snapshot.children){
val list=childSnapshot.getValue(CategoryModel::class.java)
if(list!=null){
lists.add(list)
}
}
_category.value=lists
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
}
}
activity_main.xml (The relevant part of main.xml regarding the question. I used ScrollView on top of it as well)
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="100dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/viewCategory"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
<ProgressBar
android:id="@+id/progressBarCategory"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
viewholder_category.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/light_purple_oval_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/img"
android:layout_width="30dp"
android:layout_height="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/titleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="title"
android:textColor="@color/darkPurple"
app:layout_constraintEnd_toEndOf="@+id/constraintLayout"
app:layout_constraintStart_toStartOf="@+id/constraintLayout"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
build.gradle.kts(Module :app)
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.google.gms.google.services)
}
android {
namespace = "com.example.dashboard"
compileSdk = 36
defaultConfig {
applicationId = "com.example.dashboard"
minSdk = 36
targetSdk = 36
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
viewBinding = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.firebase.database)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation(libs.androidx.recyclerview)
implementation(libs.glide.v4160)
}
I have found out why I was not getting the RecyclerView to work. Make sure to add your firebase url in the getInstance parenthesis. Mine was set in Singapore while the getInstance() is defaulted to us-central1. That is why I was not seeing anything:
MainViewModel.kt:
private val firebaseDatabase = FirebaseDatabase.getInstance("[your firebase url]")
Please check logcat located at the bottom-left corner of Android Studio. This was a rookie mistake of mine as I was looking for errors in the build section.