MachineTheGod
MachineTheGod

Reputation: 163

Kotlin - findViewById causes app to close imediatelly after lauching

I'm currently learning Kotlin and as I was following a BottomNaivgationView tutorial, I came across this error where the app immediately closes after launch. After many tests, I got to find that this being caused by the findViewbyId() I have implemented to pick a view from the menu. However, I do not know how to fix it.

MainActivity.kt


val TAG = "MainActivity"
    val bottom_navigation : BottomNavigationView = findViewById(R.id.bottom_navigation)

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

        val homeFragment = HomeFragment()
        val listsFragment = ListsFragment()
        val searchFragment = SearchFragment()

        bottom_navigation.setOnNavigationItemSelectedListener {
            when (it.itemId) {
                R.id.nav_home -> {
                    setCurrentFragment(homeFragment)
                    Log.i(TAG, "Home Selected")
                }
                R.id.nav_lists -> {
                    setCurrentFragment(listsFragment)
                    Log.i(TAG, "My Lists Selected")
                }
                R.id.nav_search -> {
                    setCurrentFragment(searchFragment)
                    Log.i(TAG, "Search Selected")
                }
            }
            true
        }

    }

    private fun setCurrentFragment(fragment : Fragment) =
        supportFragmentManager.beginTransaction().apply {
            replace(R.id.fl_wrapper, fragment)
            commit()
        }

activity_main.xml


<RelativeLayout 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=".MainActivity">

    <FrameLayout
        android:id="@+id/fl_wrapper"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottom_navigation" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:id="@+id/bottom_navigation"
        android:layout_alignParentBottom="true"
        android:background="?android:attr/windowBackground"
        app:itemBackground="@color/colorPrimary"
        app:itemIconTint="@drawable/nav_item_colour_selected"
        app:labelVisibilityMode="unlabeled"
        app:menu="@menu/bottom_nav_menu"/>

</RelativeLayout>

Upvotes: 3

Views: 123

Answers (2)

iamwent
iamwent

Reputation: 111

You can use the lazy properties.

val bottom_navigation: BottomNavigationView by lazy { findViewById(R.id.bottom_navigation) }

Upvotes: 1

Zain
Zain

Reputation: 40840

You can't call findViewById() before setting the activity layout using setContentView(R.layout.activity_main) in onCreate() activity lifecycle method..

Before onCreate() & setContentView(R.layout.activity_main) the activity class/behavior is yet to be attached to its view/layout. So there is no layout in order to find a view in..

So you need to transfer the

val bottom_navigation : BottomNavigationView = findViewById(R.id.bottom_navigation)

To be:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val bottom_navigation : BottomNavigationView = findViewById(R.id.bottom_navigation)
    val homeFragment = HomeFragment()
    //......

Upvotes: 1

Related Questions