0

I try to implement a BottomNavigationMenu in my app using the Jetpack navigation. I followed each step of this tutorial https://www.youtube.com/watch?v=pT_4rV3gO78 but unfortunately I could not integrate into my app and I get an error when starting the app

java.lang.RuntimeException: Unable to start activity ...

     Caused by: java.lang.NullPointerException: Attempt to read from field 'com.google.android.material.bottomnavigation.BottomNavigationView com.example.td.barapp.databinding.ActivityMainBinding.bottomNavigation' on a null object reference
        at com.example.td.barapp.MainActivity.onCreate(MainActivity.java:28)

The error pinpoints to my main activy which has the follwing java code:

package com.example.td.barapp;

import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;

import android.os.Bundle;

import com.example.td.barapp.databinding.ActivityMainBinding;


public class MainActivity extends AppCompatActivity  {

   
    private ActivityMainBinding binding;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        DataBaseEntries.createDataBaseEntries(drinksDB);

        NavController navController = Navigation.findNavController(this, R.id.navHostfragment);

        NavigationUI.setupWithNavController(binding.bottomNavigation,navController );


    }
}

So it says that the NavController is null. Why is it null and how can make it not null?

Here you can see the XML file of the Main Activity with the NavHostFragment:

<?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=".MainActivity"
    tools:ignore="ExtraText">


    <fragment
        android:id="@+id/navHostfragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        app:labelVisibilityMode="labeled"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorGreen"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_navigation"
        app:itemIconTint="@color/colorPrimaryDark"
        app:itemTextColor="@color/colorAccent"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

And here you can see the XML file of the ButtonNavigationMenu, in which I linked the destination to the ID of the NavGraph (android:id="@+id/FR_LanguageSelection"):

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <item
        android:id="@+id/FR_LanguageSelection"
        android:icon = "@drawable/ic_add_circle_full"
        android:title = "Language" />



</menu>

Do you have an idea why I can't start the app and get this error? Without the BottomNavigationMenu in the JavaCode the app works and the BottomNavigationView is displayed correctly (but of course I can't use it for navigation). I'd appreciate every answer and would be quite thankful for your help.

VanessaF
  • 515
  • 11
  • 36

2 Answers2

1

there are a few things off in my eyes

-I don't think it's the issue but for data binding, you need to wrap your XML file in <layout> attribute I guess you just didn't put it here but if that's the case fix it.

-you need to be sure that your menu item id witch is FR_LanguageSelection here be the same as your destination fragment id

-you need to navigate using actions that are declared in your nav_graph but there is nothing here

check these and if these are not the case let me know

ErfanDP
  • 171
  • 5
  • Thanks ErfanDP for your answer and effort. Basically I do not understand your first point with the . As said in the question, without the Java Code of the Bottom Navigation everything is displayed correctly (including the BottomNavigationMenu) but I just can't navigate. Regarding your second point, I just copied the id from the navGraph so it is the same – VanessaF Jan 10 '21 at 12:29
  • Regarding your 3rd point with the navGraph. Bascially my NavGraph has more than 20 entries (as I use more than 20 different fragments). The navigation without the BottomNavigationMenu works fine using the Jetpack components. Shall I have a link from each of the 20 Fragments to the destination fragment (FR_LanguageSelection) of the BottomNavigationView? – VanessaF Jan 10 '21 at 12:32
  • @VanessaF for DataBinding classes to be generated you need to wrap your entire XML fragments and activities that want to use data binding with layout attribute here is my fairly incomplete project but I completely implement DataBinding and NavCombponent with bottom nav with this you probably will understand my points : https://github.com/ErfanDP/WoocommerceMarket check out list XML files for example for my first point and look at navigating in my single Activity – ErfanDP Jan 10 '21 at 14:18
  • Okay, I put everything in the oncreateView method and now I at least do not get the starting null error and the app can be started. However, the navigation does not work. When I click on the button of the ButtomNavigationBar nothing happens – VanessaF Jan 10 '21 at 14:24
  • This is my onCreateView method now "public View onCreateView({at}NonNull LayoutInflater inflater, {at}Nullable ViewGroup container, {at}Nullable Bundle savedInstanceState) { binding = ActivityMainBinding.inflate(inflater, container, false); NavController navController = Navigation.findNavController(this, R.id.navHostfragment); NavigationUI.setupWithNavController(binding.bottomNavigation,navController ); return binding.getRoot(); }" – VanessaF Jan 10 '21 at 14:26
  • Thanks Erfan for your answer. I upvoted it. Basically the navigation still does not work. What exactly do I have to specify in the navigation graph? – VanessaF Jan 11 '21 at 20:47
  • the only thing that crosses my mind witch could be wrong is this https://developer.android.com/guide/navigation/navigation-getting-started#Designate-start – ErfanDP Jan 12 '21 at 05:47
  • Thanks Erfan for your further comment and effort. I really appreciate it. Do I have to link all the fragments which include this BottomNavigation Bar to the destination fragment? I have more than 20 Fragments. Do I have to connect all of them to the destination fragments? – VanessaF Jan 12 '21 at 15:43
  • you can have multiple nav graphs to have multiple fragment back stack I only need one fragment back stack in my project but if you need more you can have that in your project but eventually, you need to set action for all of your fragments in order to navigate to them – ErfanDP Jan 13 '21 at 16:18
  • Thanks Erfan for your comment and help. I really appreciate it. So this means I have to set a link in the navGraph from all of my 25 fragments to all 5 intended fragment destinations of the BottomNavigationBar? This would bean I would have to set 25*5= 125 links? – VanessaF Jan 14 '21 at 20:29
  • What do I have to specify in the NavGraph in order to navigate via the bottom Navigation Bar. Without the bar I know how to use the navigation of the Jetpack Components. But when using the BottomNavigationBar in my main activity it just does not navigate (altough the destination names are correct) – VanessaF Jan 16 '21 at 08:37
  • there is nothing actually it will be handled automatically by itself you just need to name them correctly check this out: https://stackoverflow.com/questions/50577356/android-jetpack-navigation-bottomnavigationview-with-youtube-or-instagram-like – ErfanDP Jan 16 '21 at 10:47
  • Thanks Erfan for your answer. Well the names are indeed correct. I can be for sure about this because when putting the BottomNavigation Bar in the XML file of each of my 25 fragments and also put the navigation java code in each of my fragments, the navigation works perfectly. But when I use the approach of only having the BottomNavigationBar in the main activity (both XML and Java files) then the BottomNavigationBar is displayed but it just does not navigate – VanessaF Jan 16 '21 at 11:32
  • As stated before. I know how to use the Jetpack Navigation components and in my app it is possible to navigate from one fragment to others after e.g. having pressed a button (I use the navigation graph). Both when having a BottomNavigationBar the navigation just does not work and I still have no idea at all why it does not work – VanessaF Jan 16 '21 at 11:34
1

When using data binding you use setContentView differently:

binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Dorian Pavetić
  • 123
  • 1
  • 8
  • Thanks for your answer Dorian. When using your suggested code I get the following runtime error: com.example.td.barapp:layout/activity_main: Error inflating class fragment Caused by: android.view.InflateException: Binary XML file line #11 in com.example.td.barapp:layout/activity_main: Error inflating class fragment Caused by: java.lang.IllegalArgumentException: Binary XML file line #11: Duplicate id 0x7f0a0110, tag null, or parent id 0xffffffff with another fragment for androidx.navigation.fragment.NavHostFragment – VanessaF Jan 10 '21 at 14:17
  • Okay, I put everything in the oncreateView method and now I at least do not get the starting null error and the app can be started. However, the navigation does not work. When I click on the button of the ButtomNavigationBar nothing happens – VanessaF Jan 10 '21 at 14:23
  • For that you would need to add more items into your menu.xml and add fragments to navigation.xml. Check if your ID's match. And I also noticed I missed one line in my answer, I have just edited it – Dorian Pavetić Jan 10 '21 at 14:43
  • Thanks for your answer Dorian. I upvoted it. Can you tell me what I have to specify in the navigation graph in order to make the navigation work? Bascially at the moment the fragments can be seen in the navigation graph but they are not linked – VanessaF Jan 11 '21 at 20:46
  • There are dozens of tutorials for that implementation on the internet, this is official doc: https://developer.android.com/guide/navigation/navigation-getting-started – Dorian Pavetić Jan 12 '21 at 19:23
  • Hi Dorian. Thanks for your comment. Basically as said before I know how to use the JetPackNavigation Components and I have already used it several times without problems. Things get complicated when using the Bottom Navigation Bar – VanessaF Jan 15 '21 at 18:21
  • I have to add the following code in every fragment (and I have about 25 fragment) otherwise it does not navigate: NavController navController = Navigation.findNavController(getActivity(), R.id.navHostfragment); NavigationUI.setupWithNavController(binding.bottomNavigation,navController ); And I have to define the bottom navigation bar in every xml layout file of the fragments. I thought I cought just define it one in the activity (I use one activity and multiple fragments). But this does not work as the command "binding.bottomNavigation" can't find the bottomNavigation – VanessaF Jan 15 '21 at 18:21
  • You did something wrong. You can't use Activity binding in your fragments, instead use: getActivity().findViewById(R.id.bottomNavigation);. Putting bottom navigation in every fragment is deeply wrong. But thats matter for another topic, I suggest u mark correct answer if it solved your problem. – Dorian Pavetić Jan 15 '21 at 18:34
  • Thanks Dorian for your comment. Bascially altough I also think that I am doing something wrong the navigation works as wanted with my approach. As said I have to put the navigationBar in every XML file of the 25 fragments and I have to put the code posted above in every Java file of the fragments. If I have done this, I do not even need to specify the links in the NavGraph. This also suprises me but it works exactly as desired. – VanessaF Jan 15 '21 at 18:51
  • Do you see any downside of my approach (except that I have to copy and paste the same code for all XML-layout files and all Java files)? Because I have spent quite much time into making this BottomNavigation Bar work and now that it works I do not want to change anything (or use another approach) as I think that this will create new problems – VanessaF Jan 15 '21 at 18:54
  • What do you mean by saying "You can't use Activity binding in your fragments". Bascially I do not really do this. I just use "Navigation.findNavController(getActivity(), R.id.navHostfragment);" and "NavigationUI.setupWithNavController(binding.bottomNavigation,navController )" in every Java Fragment. the binding.bottomNavigation is not the Acticity binding but the Fragment binding (this is why I have to put the bottomNavigationBar in every XML-layout file of the fragment; otherwise the Fragment Bindding can't find it) – VanessaF Jan 15 '21 at 18:57
  • Thats a lot of boiler plate code. You should have set one bottom navigation in your main activity, setup navigation controller for it, and setup navigation.xml for every menu. In my personal opinion best solution so far is navigation extensions (google it). Even tho its written in kotlin, you can still use it, and it will automatically handle your fragments and save their states. So you can have navigation graphs for each bottom navigation item separately. – Dorian Pavetić Jan 15 '21 at 19:30
  • Thanks Dorian for your answer and effort. Basically at the beginning I had the bottom navigation bar in the main activity and took some time (inital question) to start the app without an error. Then I managed to do so and I only had the BottomNavigation bar in the Java code of the main activity. Altough it was shown in the app the navigation did not take place. I tried a lot (with and without the navGraph) but the navigation just did not work. This is why I came to my current solution – VanessaF Jan 15 '21 at 20:48
  • This is what I was also asking to you. When I have the BottomNavigation Bar only in the main Activity (both in XML and Java) what else do I have to do (maybe in the Navigation Graph) to make it navigate to the desired destinations (the destination names were all correct but it simply did not navigate)? You gave me a linkt to the general Jetpack Navigation in Android (that I do understand) but there it is also mentioned that I should use something like "NavigationUI.setupWithNavController(binding.bottomNavigation,navController )" which led me to my current solution. – VanessaF Jan 15 '21 at 20:51
  • By the way: I added your suggested additional code "setContentView(binding.getRoot());" but this did not change anything. The BottomNavigaitonView is seeable when using it in the main activity but the navigation does not work – VanessaF Jan 16 '21 at 09:49
  • Any comments on my last comments? I'd highly appreciate any further input from you as I am struggeling on this one – VanessaF Jan 17 '21 at 11:15
  • This is completely another matter, and I can't make guesses whats wrong based on nothing, without any code or some feedback, and write codes in comments – Dorian Pavetić Jan 17 '21 at 11:16
  • Thanks Dorian for your help and effort. I really appreciate it. I have accepted your answer and I have posted a new question about my problem with the BottomNavigationBar that you can see here:https://stackoverflow.com/questions/65851215/bottomnavigation-menu-with-jetpack-navigation-does-not-navigate – VanessaF Jan 22 '21 at 19:01