Search code examples
android-fragmentskotlinandroid-listview

ListView ID called on null? (Kotlin)


I'm new to Kotlin and im trying to build a HomePage where there is a BottomNavigation with 3 Fragment pages but in 1 of the pages I set a ListView and whenever I call the ID it gives the following errer(Caused by: java.lang.IllegalStateException: categoryListView must not be null)

Here is how Im calling it in my HomePage which is where the content appears:

class HomePage : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    lateinit var adapter : CategoryAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home_page)

        adapter = CategoryAdapter(this, DataService.categories)
        categoryListView.adapter = adapter

        navView.setNavigationItemSelectedListener(this)

        bottomNavigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)

        replaceFragment(HomeFragment())
    }

    private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when(item.itemId) {
            R.id.Bottom_Nav_Home -> {
                println("Home pressed")
                replaceFragment(HomeFragment())
                return@OnNavigationItemSelectedListener true
            }
            R.id.Bottom_Nav_Notifs -> {
                println("Notification pressed")
                replaceFragment(NotifsFragment())
                return@OnNavigationItemSelectedListener true
            }
            R.id.Bottom_Nav_List -> {
                println("List pressed")
                replaceFragment(ListFragment())
                return@OnNavigationItemSelectedListener true
            }
        }
        false
    }

    private fun replaceFragment(fragment: Fragment) {
        val fragmentTransaction = supportFragmentManager.beginTransaction()
        fragmentTransaction.replace(R.id.NavPageFragment, fragment)
        fragmentTransaction.commit()
    }
}

am I doing it correct? or am I supposed to call the categoryListView elsewhere? because I tried in my ListFragment which is where my activity code is and it gave a context error

here is how the Fragment activity looks:

<?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:id="@+id/Bottom_List"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Fragments.ListFragment">

    <ListView
        android:id="@+id/categoryListView"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Solution

  • You are trying to get the categoryListView resolved inside the activity but it is (as far as I understand) part of the fragment. This simply does not work.

    The CategoryAdapter and the ListView should be used inside your HomeFragment class and this will work then.

    So move this code into your fragment:

    adapter = CategoryAdapter(this, DataService.categories)
    categoryListView.adapter = adapter
    

    Update

    I would move it into the onViewCreated() method. There you can simply rely on the fact that there is a view available with a context.

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        adapter = CategoryAdapter(view.context, DataService.categories)
        categoryListView.adapter = adapter // categoryListView will be not null here
    }