Mehul Kanzariya
Mehul Kanzariya

Reputation: 1348

Error in finding NavHostFragment Jetpack Navigation Android

I am using Jetpack Navigation for handling the navigation of Fragments. After following the documentation, when I run the app I am getting the below error.

Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.navigation.fragment.NavHostFragment" 

build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
compileSdkVersion 'android-P'

defaultConfig {
    applicationId "com.meditab.imspatient"
    minSdkVersion 21
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {

def nav_version = "1.0.0-alpha01"

implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation 'androidx.constraintlayout:constraintlayout:1.1.0' // Constraint layout

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // Kotlin

// Anko
implementation "org.jetbrains.anko:anko-commons:$anko_version" // Anko Commons
implementation "org.jetbrains.anko:anko-design:$anko_version" // For SnackBars
implementation "org.jetbrains.anko:anko-coroutines:$anko_version" // Anko Coroutines

// Support libraries
implementation 'androidx.legacy:legacy-support-v4:1.0.0-alpha1' // Support v4
implementation 'androidx.appcompat:appcompat:1.0.0-alpha1' // AppCompat
implementation 'androidx.recyclerview:recyclerview:1.0.0-alpha1' // RecyclerView
implementation 'com.google.android.material:material:1.0.0-alpha1' // Design Support library
implementation 'androidx.cardview:cardview:1.0.0-alpha1' // CardView

// Jetpack Navigation
implementation "android.arch.navigation:navigation-fragment-ktx:$nav_version"
implementation "android.arch.navigation:navigation-ui-ktx:$nav_version"

// Dagger 2
implementation 'com.google.dagger:dagger:2.14.1'
kapt 'com.google.dagger:dagger-compiler:2.14.1'
provided 'javax.annotation:jsr250-api:1.0'

// Retrofit, OkHttp, OkHttpInterceptor and GSON
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'

implementation 'com.rengwuxian.materialedittext:library:2.1.4' // Material EditText
 }

kotlin {
experimental {
    coroutines "enable"
}
}

Code of the Activity hosting the NavHostFragment

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

// Handle the clicks for bottom navigation view
bottom_navigation_view_homepage_activity.setOnNavigationItemSelectedListener { item ->


    when (item.itemId) {
        R.id.action_appointment -> findNavController(item.itemId).navigate(R.id.appointmentFragment)

        R.id.action_chat -> findNavController(item.itemId).navigate(R.id.chatFragment)
    }



}

Navigation.findNavController(this, R.id.appointmentFragment)

}

Activity's XML file

 <?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">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"
       />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation_view_homepage_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        app:itemIconTint="@drawable/nav_item_color_state"
        app:itemTextColor="@drawable/nav_item_color_state"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_navigation_view" />
</androidx.constraintlayout.widget.ConstraintLayout>

I have implemented the Navigation Graph properly. Also, the project is refactored to AndroidX.

Upvotes: 3

Views: 4925

Answers (4)

moumenShobakey
moumenShobakey

Reputation: 426

Did you add the fragment dependency? implementation "androidx.fragment:fragment:1.2.0" this is for java i don't know if it's the same for kotlin

Upvotes: 0

Yudi karma
Yudi karma

Reputation: 324

Please check if your 'id_menu' called in BottomNavigation is the same as 'id_fragment' in the Navigation Graph.

You can use this method to navigate 'bottom_nav' to show a fragment:

setSupportActionBar(toolbar)

    navController = Navigation.findNavController(this, R.id.main_fragment)
    NavigationUI.setupWithNavController(bottom_nav,navController)
    NavigationUI.setupActionBarWithNavController(this, navController)

and don't forget to overide the following method:

override fun onSupportNavigateUp(): Boolean {
    return NavigationUI.navigateUp(navController,null)
}

Please let me know if this code works for you.

As an aside, with Kotlin you don't need call findViewById, you might find benefit by implementing DataBinding in your layout.

Upvotes: 0

Wang
Wang

Reputation: 1038

If this issue happens while using a release build, chances are that the class name has been minified by proguard. That way, the reference android:name="androidx.navigation.fragment.NavHostFragment" in the XML file will not match any valid class.

Try to add this line in the proguard file

-keepnames class androidx.navigation.fragment.NavHostFragment

so that the class name does not get minified and that it stays as mentionned in the XML file.

Upvotes: 6

Ankit Bisht
Ankit Bisht

Reputation: 1269

Try to call Navigation.findNavController(bottom_navigation_view_homepage_activity, R.id.appointmentFragment)

You also don't need to set setOnNavigationItemSelectedListener, just edit your navigation graph "nav_graph" as follow:

<fragment
        android:id="@+id/action_appointment"
        ..../>
<fragment
        android:id="@+id/action_chat"
        ..../>

Basically set your fragment id in nav_graph same as the item ids in your bottom nav view.

Upvotes: 0

Related Questions