'Kotlin null object reference on recyclerview when ids match

I know this is a basic question but it's been doing my head in all day.

Error: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference

As you can see below the ID for the recyclerview and where I am calling the recyclerview in mainactivity are the same, so I am really stumped as to why this is returning a null object reference. Any insight will be greatly appreciated.

MainActivity.kt

val bottomNavigation = findViewById<BottomNavigationView>(R.id.bottom_navigation)
        bottomNavigation.setOnNavigationItemSelectedListener {
            when (it.itemId) {
                R.id.ic_home -> makeCurrentFragment(homeFragment)
                R.id.ic_search -> makeCurrentFragment(searchFragment)
                R.id.ic_collections -> loadSavedRecipes()
                R.id.ic_account -> if (loggedIn) makeCurrentFragment(accountLoggedInFragment) else makeCurrentFragment(accountFragment)
            }
            true
        }

..............................

internal fun saveRecipe() {
    allSavedRecipes.add(savedRecipe)
    Toast.makeText(this, "Recipe added to favourites", Toast.LENGTH_SHORT).show()
}

private fun loadSavedRecipes() {
    makeCurrentFragment(savedRecipesFragment)
    var savedRecipeCount: Int = allSavedRecipes.count()
    if (savedRecipeCount > 0) {
        savedRecipesRV.layoutManager = GridLayoutManager(this@MainActivity, savedRecipeCount, GridLayoutManager.HORIZONTAL, false)
        savedRecipesRV.adapter = SavedRecipesAdapter(allSavedRecipes)
    }
}

SavedRecipesFragment.kt

class SavedRecipesFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_saved_recipes, container, false)
    }

}

SavedRecipesAdapter

class SavedRecipesAdapter(private val savedrecipes: List<SavedRecipes>) :
    RecyclerView.Adapter<SavedRecipesAdapter.ViewHolder>(){

    override fun getItemCount(): Int {
        return savedrecipes.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(parent.context)
                .inflate(R.layout.saved_recipes_layout, parent, false)
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val theRecipe = savedrecipes.get(position)

        holder.name.text = theRecipe.title
        holder.minutes.text = theRecipe.time
        holder.servings.text = theRecipe.servings
        Picasso.get().load(theRecipe.image).into(holder.img)
    }

    class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {
        val name: TextView = view.savedRecipeName
        val minutes: TextView = view.savedRecipeMinutes
        val servings: TextView = view.savedRecipeServings
        val img = view.savedRecipeImg
    }
}

saved_recipes_layout.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/savedRecipeCard"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@drawable/recipe_result_card_background"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/savedRecipeImg"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="5dp"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintBottom_toBottomOf="@+id/savedRecipeCard"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/savedRecipeCard" />

    <TextView
        android:id="@+id/savedRecipeName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:text="TextView"
        android:textColor="@color/black"
        android:textStyle="bold"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="@+id/savedRecipeCard"
        app:layout_constraintStart_toEndOf="@+id/savedRecipeImg"
        app:layout_constraintTop_toTopOf="@+id/savedRecipeCard" />

    <TextView
        android:id="@+id/savedRecipeMinutes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_marginLeft="10dp"
        android:text="75"
        android:textColor="@color/black"
        app:layout_constraintStart_toEndOf="@+id/savedRecipeImg"
        app:layout_constraintTop_toBottomOf="@+id/savedRecipeName" />

    <TextView
        android:id="@+id/savedRecipeMinutesTxt"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="5dp"
        android:text="Minutes"
        android:textColor="@color/black"
        app:layout_constraintEnd_toEndOf="@+id/savedRecipeCard"
        app:layout_constraintStart_toEndOf="@+id/savedRecipeMinutes"
        app:layout_constraintTop_toBottomOf="@+id/savedRecipeName" />

    <TextView
        android:id="@+id/savedRecipeServings"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="564"
        android:textColor="@color/black"
        app:layout_constraintStart_toEndOf="@+id/savedRecipeImg"
        app:layout_constraintTop_toBottomOf="@+id/savedRecipeMinutes" />

    <TextView
        android:id="@+id/savedRecipeServingsTxt"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="Servings"
        android:textColor="@color/black"
        app:layout_constraintEnd_toEndOf="@+id/savedRecipeCard"
        app:layout_constraintStart_toEndOf="@+id/savedRecipeMinutes"
        app:layout_constraintTop_toBottomOf="@+id/savedRecipeMinutesTxt" />



</androidx.constraintlayout.widget.ConstraintLayout>

fragment_saved_recipes.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="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragments.SavedRecipesFragment">

    <TextView
        android:id="@+id/savedRecipesHeader"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="My Saved Recipes"
        android:textColor="@color/black"
        android:textAlignment="center"
        android:textStyle="bold"
        android:textSize="24sp"
        android:layout_marginVertical="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:fadeScrollbars="true"
        android:overScrollMode="never"
        android:scrollbars="vertical"
        android:layout_marginTop="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/savedRecipesHeader">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/savedRecipesRV"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:overScrollMode="never" />

        </LinearLayout>

    </androidx.core.widget.NestedScrollView>


</androidx.constraintlayout.widget.ConstraintLayout>


Solution 1:[1]

Most likely you are trying to set a layout manager before the OnCreateView() is called. You can actually just add a layout manager from XML if you like:

 <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/savedRecipesRV"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:overScrollMode="never" 
               app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

/>

but it would definitely be best to set up your UI components after they are inflated. You can do that in onViewCreated, onResume, or onStart depending on your needs.

Solution 2:[2]

Solved through handling the functionality through the fragment class:

class SavedRecipesFragment : Fragment() {

lateinit var savedRecipesRV: RecyclerView
var allSavedRecipesPass = mutableListOf<SavedRecipes>()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val view = inflater.inflate(R.layout.fragment_saved_recipes, container, false)
    savedRecipesRV = view.findViewById(R.id.savedRecipesRecyclerView)
    return view
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    DisplaySavedRecipes()
}

override fun onResume() {
    super.onResume()
    DisplaySavedRecipes()
}

fun DisplaySavedRecipes() {
    allSavedRecipesPass = (activity as MainActivity).allSavedRecipes
    
    var savedRecipeCount: Int = allSavedRecipesPass.count()

    if (savedRecipeCount > 0) {
        savedRecipesRV.layoutManager = GridLayoutManager(context, savedRecipeCount, GridLayoutManager.HORIZONTAL, false)
        savedRecipesRV.adapter = SavedRecipesAdapter(allSavedRecipesPass)
    }
}

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Nat M 18