Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
113 views
in Technique[技术] by (71.8m points)

android - BottomNavigation Menu with Jetpack Navigation does not navigate

I have a strange problem regarding a BottomNavigationBar which I could not solve altough having spent a huge amount of time into it. When I use it in the 'recommended' way (from many tutorials) it just does not navigate.

So what do I mean by 'recommended' way: I have a single acticity with a navHostFragment called 'MainActivity'. This main activity has a XML layout file in which I put the BottomNavigationBar. The BottomNavigationBar also has a XML layout file. Now I have a Fragment called 'FR_Menu' with a Java file and a XML layout file. I also have a NavGraph. In the XML layout of the Fragment 'FR_Menu' I do not use the BottomNavigationBar and in the Java class I do not instantiate the BottomNavigationBar as I have already done this in the main Activity. But using this approach the Navigation does not work. Altough the BottomNavigationBar is correctly displayd in the Fragment 'FR_Menu', when clicking on the Bottom just nothing happens.

Now here come the strange thing. When I use the code as posted, but not put the BottomNavigationBar in the XML layout file of the main activity and instead put it separately in every XML-layout file of all Fragments (in this example the fragment 'FR_Menu') and when I also instantiate the BottomNavigationBar in every Java file of each Fragment (in this example the fragment 'FR_Menu'), then the Navigation works perfectly. So with this approach I have to put the BottomNavigationBar in every XML layout file of the fragments and also I have to instantiate the BottomNavigationBar in every Java file of the Fragments. I know that normally using the Jetpack Navigation components, this should not be the case and instead I should only have to instantiate once in the MainActivity as the BottomNavigationBar should only be added to the XML layout file of the MainActivity.

Does anyone have an idea what goes wrong when I am trying to implement the 'recommended' approach? The names are all correct (maybe there is a small error in my shown example because I had to simplify and adjust it a little bit), because when using the second approach (putting the BottomNavigationBar in every XML-layout file and in every Java file of the fragments) the navigation works perfectly (I also tried it with multiple items and destinations).

I have really spent quite much time on that and I could not figure out what my mistake it. Because of this I would highly appreciate every comment and would be quite thankful for your help.

Does anyone have an idea what the reason for this strange behaviour might be?

Java code of the 'MainActivity':

package com.example.td.bapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

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


public class MainActivity extends AppCompatActivity  {

   
    private  ActivityMainBinding binding;


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


    }

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        binding = ActivityMainBinding.inflate(inflater, container, false);
        NavController navController = Navigation.findNavController(this, R.id.navHostfragment);
        NavigationUI.setupWithNavController(binding.bottomNavigation,navController );
        setContentView(binding.getRoot());
        return binding.getRoot();
    }

}

XML layout file of the 'MainActivity':

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

XML-layout file of BottomNavigationBar:

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

Java file of the Fragment 'FR_Menu'

package com.example.td.bapp;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;

import com.example.td.bapp.databinding.ActivityMainBinding;
import com.example.td.bapp.databinding.FragmentMenuBinding;


public class FR_Menu extends Fragment implements View.OnClickListener {


    // TODO: Rename and change types of parameters



    public FR_Menu() {

    }


    public static FR_Menu newInstance(String param1, String param2) {
        FR_Menu fragment = new FR_Menu();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }

    private FragmentMenuBinding binding;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // return inflater.inflate(R.layout.fragment_menu, container, false);
        binding = FragmentMenuBinding.inflate(inflater, container, false);


        /*
       // IMPORTANT REMARK: When I use the following code in the second option this in the second option,
       with the BottomNavigationBar in the XML document, the navigation works well


        NavController navController = Navigation.findNavController(getActivity(), R.id.navHostfragment);
        NavigationUI.setupWithNavController(binding.bottomNavigation,navController );
    */

        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        binding.imageButton_A.setOnClickListener(this);
        binding.imageButton_B.setOnClickListener(this);


    }

    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }


    @Override
    public void onClick(View view) {



        if(view.getId() == R.id.imageButton_A) {
            String argument = DataBaseEntries.A;

            FR_MenuDirections.ActionFRMenuToFRGenericD action =
                    FR_MenuDirections.actionFRMenuToFRGenericD(argument);
            Navigation.findNavController(view).navigate(action);
        }


        if(view.getId() == R.id.imageButton_B) {
            String argument = DataBaseEntries.B;

            FR_MenuDirections.ActionFRMenuToFRGenericD action =
                    FR_MenuDirections.actionFRMenuToFRGenericD(argument);
            Navigation.findNavController(view).navigate(action);
        }







    }
}

Here is the XML layout file of the fragment 'FR_Menu'

<?xml version="1.0" encoding="utf-8"?>


<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">



    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar_mainActivity"
        android:layout_width="match_parent"
        android:layout_height="135dp"
        android:background="#435cb53f"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:titleTextColor="@android:color/holo_green_light">

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:layout_gravity="center"
            android:textColor="@android:color/white"
            android:textSize="24sp"
            android:text="Menu" />
    </androidx.appcompat.widget.Toolbar>

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layo

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

onCreateView is a method of a Fragment, not a method on Activity, so your method in your MainActivity isn't ever called by the framework.

In fact, that code isn't what you'd use in an Activity at all as per the View Binding documentation.

Therefore your MainActivity should instead look like:

public class MainActivity extends AppCompatActivity  {
   
    private  ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Inflate, and then call setContentView() on the returned view root
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        
        NavController navController = Navigation.findNavController(this,
            R.id.navHostfragment);
        NavigationUI.setupWithNavController(binding.bottomNavigation, navController);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...