Remove Bottom Navigation view with fragments
Asked Answered
P

4

2

I have 2 activities with a separate NavHostFragment which hosts 3 fragments, these 3 fragments are then displayed in my activity's layout ContainerView. Note: My 2 activities have the same name and use the same layout, the only difference is that they are in different directories and handle slightly different tasks.

Initially, I planned on using all fragments for the app but now, I decided to use only one for the first release, then work on the others later because it was tasking to handle all at once

So I want to safely remove the bottom navigation view and the other two fragments(second & third fragment).

Already, I have initially tried doing it on my own by deleting those fragments and erasing any code related to it but it came up with a lot of errors, so I decided to bring it here to see if anyone could help with the safest possible way that I could remove them so that my first fragment can continue to function without any issues.

It is a weather app, so I receive current city updates on the first fragment. I was supposed to receive hourly & daily updates on the second & third fragments but I've halted my plan, for now, I want to use only the first fragment.

Here are the principal codes:

Activity\HomeActivity:

public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    private DrawerLayout drawer;
    // Last update time, click sound, search button, search panel.
    TextView timeField;
    MediaPlayer player;
    ImageView Search;
    EditText textfield;
    // For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
    ConstraintLayout constraintLayout;
    public static int count = 0;
    int[] drawable = new int[]{R.drawable.nyc, R.drawable.lofoten_islands, R.drawable.parque, R.drawable.moraine_lake, R.drawable.eiffel_tower,
            R.drawable.whitehaven_beach, R.drawable.london, R.drawable.cape_town, R.drawable.burj_al_arab,R.drawable.atuh_beach};
    Timer _t;

    private WeatherDataViewModel viewModel;
    private AppBarConfiguration appBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        // use home activity layout.

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Allow activity to make use of the toolbar

        drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        // Hiding default Drawer fragment that has the BottomNavView
        navigationView.getMenu().findItem(R.id.main_id).setVisible(false);

        viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);

        // Trigger action to open & close navigation drawer
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
                , R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        timeField = findViewById(R.id.textView9);
        Search = findViewById(R.id.imageView4);
        textfield = findViewById(R.id.textfield);
        //  find the id's of specific variables.


        BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
        // host 3 fragments along with bottom navigation.
        final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        assert navHostFragment != null;
        final NavController navController = navHostFragment.getNavController();

        // Make hourly & daily tab unusable
        bottomNavigationView.setOnNavigationItemSelectedListener(item -> {

            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                getSupportFragmentManager().popBackStack();
            }
            return false;
        });

        toggle.setToolbarNavigationClickListener(v -> {
            // Enable the functionality of opening the side drawer, when the burger icon is clicked
            toggle.setDrawerIndicatorEnabled(true);
            navController.navigate(R.id.main_id);
        });

        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        // remove up button from all these fragments
        appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.main_id) // remove up button from all these fragments >> Keep up button in R.id.nav_setting, R.id.nav_slideshow
                .setOpenableLayout(drawer)
                .build();

        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

        // navController.addOnDestinationChangedListener((controller, destination, arguments) -> navController.popBackStack(destination.getId(), false));
        // navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
        // });

        navController.addOnDestinationChangedListener((controller, destination, arguments) -> {

            // Hide/show top search bar
            if (destination.getId() == R.id.main_id) {
                Search.setVisibility(View.VISIBLE);
                textfield.setVisibility(View.VISIBLE);

            } else {
                Search.setVisibility(View.GONE);
                textfield.setVisibility(View.GONE);
            }

            // Fragments that you want to show the back button
            if (destination.getId() == R.id.about_id || destination.getId() == R.id.privacy_policy_id) {
                // Disable the functionality of opening the side drawer, when the burger icon is clicked
                toggle.setDrawerIndicatorEnabled(false);
            }

        });

        // For scheduling background image change
        constraintLayout = findViewById(R.id.layout);
        constraintLayout.setBackgroundResource(R.drawable.nyc);
        _t = new Timer();
        _t.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                // run on ui thread
                runOnUiThread(() -> {
                    if (count < drawable.length) {

                        constraintLayout.setBackgroundResource(drawable[count]);
                        count = (count + 1) % drawable.length;
                    }
                });
            }
        }, 5000, 5000);

        Search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // make click sound when search button is clicked.
                player = MediaPlayer.create(HomeActivity.this, R.raw.click);
                player.start();

                getWeatherData(textfield.getText().toString().trim());
                // make use of some fragment's data

                Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
                if (currentFragment instanceof FirstFragment) {
                    FirstFragment firstFragment = (FirstFragment) currentFragment;
                    firstFragment.getWeatherData(textfield.getText().toString().trim());
                } else if (currentFragment instanceof SecondFragment) {
                    SecondFragment secondFragment = (SecondFragment) currentFragment;
                    secondFragment.getWeatherData(textfield.getText().toString().trim());
                } else if (currentFragment instanceof ThirdFragment) {
                    ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
                    thirdFragment.getWeatherData(textfield.getText().toString().trim());
                }
            }

            private void getWeatherData(String name) {

                ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

                Call<Example> call = apiInterface.getWeatherData(name);

                call.enqueue(new Callback<Example>() {
                    @Override
                    public void onResponse(@NonNull Call<Example> call, @NonNull Response<Example> response) {

                        try {
                            assert response.body() != null;
                            timeField.setVisibility(View.VISIBLE);
                            timeField.setText("First Updated:" + " " + response.body().getDt());
                        } catch (Exception e) {
                            timeField.setVisibility(View.GONE);
                            timeField.setText("First Updated: Unknown");
                            Log.e("TAG", "No City found");
                            Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                        t.printStackTrace();
                    }

                });
            }

        });
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.about_id:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
                        new About()).commit();
                break;
            case R.id.privacy_policy_id:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,
                        new Privacy_Policy()).commit();
                break;
        }
        drawer.closeDrawer(GravityCompat.START);

        return true;
    }

    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
            // Open/close drawer animation
        }
    }

    @Override
    protected void onPause () {
        super.onPause();
        if (viewModel.getMediaPlayer() != null)
            viewModel.getMediaPlayer().pause();
    }

    @Override
    protected void onResume () {
        super.onResume();
        if (viewModel.getMediaPlayer() != null) {
            viewModel.getMediaPlayer().start();
            viewModel.getMediaPlayer().setLooping(true);
        }
    }

    @Override
    public boolean onSupportNavigateUp() {
        final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        assert navHostFragment != null;
        final NavController navController = navHostFragment.getNavController();

        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp(); // navigateUp  tries to pop the backstack
    }
}

Lightweatherforecast\HomeActivity:

public class HomeActivity extends AppCompatActivity {
    private DrawerLayout drawer;
    // Last update time, click sound, search button, search panel.
    TextView timeField;
    MediaPlayer player;
    ImageView Search;
    ConstraintLayout searchbar;
    EditText textfield;
    // For scheduling background image change(using constraint layout, start counting from dubai, down to statue of liberty.
    ConstraintLayout constraintLayout;
    public static int count = 0;
    int[] drawable = new int[]{R.drawable.nyc, R.drawable.lofoten_islands, R.drawable.parque, R.drawable.moraine_lake, R.drawable.eiffel_tower,
            R.drawable.whitehaven_beach, R.drawable.london, R.drawable.cape_town, R.drawable.burj_al_arab, R.drawable.atuh_beach};
    Timer _t;

    private WeatherDataViewModel viewModel;
    private AppBarConfiguration appBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        // use home activity layout.

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Allow activity to make use of the toolbar

        drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);

        // host 3 fragments along with bottom navigation.
        final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        assert navHostFragment != null;
        final NavController navController = navHostFragment.getNavController();

        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        // remove up button from all these fragments
        appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.main_id) // remove up button from all these fragments >> Keep up button in R.id.nav_setting, R.id.nav_slideshow
                .setOpenableLayout(drawer)
                .build();

        // Hiding default Drawer fragment that has the BottomNavView
        navigationView.getMenu().findItem(R.id.main_id).setVisible(false);

        viewModel = new ViewModelProvider(this).get(WeatherDataViewModel.class);

        // Trigger action to open & close navigation drawer
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar
                , R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        timeField = findViewById(R.id.textView9);
        Search = findViewById(R.id.imageView4);
        textfield = findViewById(R.id.textfield);
        searchbar = findViewById(R.id.searchbar);
        //  find the id's of specific variables.

        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

        toggle.setToolbarNavigationClickListener(v -> {
            // Enable the functionality of opening the side drawer, when the burger icon is clicked
            toggle.setDrawerIndicatorEnabled(true);
            navController.navigate(R.id.main_id);
        });

        navController.addOnDestinationChangedListener((controller, destination, arguments) -> {

            // Hide/show top search bar
            if (destination.getId() == R.id.main_id) {
                searchbar.setVisibility(View.VISIBLE);
                toggle.setHomeAsUpIndicator(R.drawable.nav_back_arrow);
                toggle.setDrawerIndicatorEnabled(true); // <<< Add this line of code to enable the burger icon

            } else {
                searchbar.setVisibility(View.GONE);
            }

            // Fragments that you want to show the back button
            if (destination.getId() == R.id.about_id || destination.getId() == R.id.privacy_policy_id) {
                // Disable the functionality of opening the side drawer, when the burger icon is clicked
                toggle.setDrawerIndicatorEnabled(false);
            }

        });

        // For scheduling background image change
        constraintLayout = findViewById(R.id.layout);
        constraintLayout.setBackgroundResource(R.drawable.nyc);
        _t = new Timer();
        _t.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                // run on ui thread
                runOnUiThread(() -> {
                    if (count < drawable.length) {

                        constraintLayout.setBackgroundResource(drawable[count]);
                        count = (count + 1) % drawable.length;
                    }
                });
            }
        }, 5000, 5000);

        Search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // make click sound when search button is clicked.
                player = MediaPlayer.create(HomeActivity.this, R.raw.click);
                player.start();

                getWeatherData(textfield.getText().toString().trim());
                // make use of some fragment's data

                Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
                if (currentFragment instanceof MainFragment) {
                    ((MainFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
                }
            }

            private void getWeatherData(String name) {

                ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

                Call<Example> call = apiInterface.getWeatherData(name);

                call.enqueue(new Callback<Example>() {
                    @Override
                    public void onResponse(@NonNull Call<Example> call, @NonNull Response<Example> response) {

                        try {
                            assert response.body() != null;
                        } catch (Exception e) {
                            Log.e("TAG", "No City found");
                            Toast.makeText(HomeActivity.this, "No City found", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(@NotNull Call<Example> call, @NotNull Throwable t) {
                        t.printStackTrace();
                    }

                });
            }

        });
    }

    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
            // Open/close drawer animation
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (viewModel.getMediaPlayer() != null)
            viewModel.getMediaPlayer().pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (viewModel.getMediaPlayer() != null) {
            viewModel.getMediaPlayer().start();
            viewModel.getMediaPlayer().setLooping(true);
        }
    }

    @Override
    public boolean onSupportNavigateUp() {
        final NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        assert navHostFragment != null;
        final NavController navController = navHostFragment.getNavController();

//        return NavigationUI.navigateUp(navController,drawer);

        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp(); // navigateUp  tries to pop the backstack
    }
}

MainFragment(The Navhost fragment):

public class MainFragment extends Fragment {

    private NavHostFragment navHostFragment;

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

        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//
        BottomNavigationView bottomNavigationView = rootView.findViewById(R.id.bottomNavigationView);

        navHostFragment = (NavHostFragment) getChildFragmentManager().findFragmentById(R.id.nav_host_fragment_content_bottom_nav_view);
        if (navHostFragment != null) {
            NavController navController = navHostFragment.getNavController();
            NavigationUI.setupWithNavController(bottomNavigationView, navController);
        }

        requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                // Exit the app when back is pressed
                requireActivity().finish();
            }
        });

        return rootView;

    }

    public void getWeatherData(String name) {

        Fragment currentFragment = navHostFragment.getChildFragmentManager().getFragments().get(0);
        if (currentFragment instanceof FirstFragment) {
            FirstFragment firstFragment = (FirstFragment) currentFragment;
            firstFragment.getWeatherData(name);
        } else if (currentFragment instanceof SecondFragment) {
            SecondFragment secondFragment = (SecondFragment) currentFragment;
            secondFragment.getWeatherData(name);
        } else if (currentFragment instanceof ThirdFragment) {
            ThirdFragment thirdFragment = (ThirdFragment) currentFragment;
            thirdFragment.getWeatherData(name);
        }
    }
}

Others include:

*FirstFragment 
*SecondFragment
*ThirdFragment with their respective layouts
*Navigation and menu layouts.

I will not post them, for now, to reduce complexity if needed please don't hesitate to ask.

Pestilential answered 10/9, 2022 at 10:37 Comment(2)
Hi Richard, I couldn't remember when did you add another activity; did we have an involved question that you thankfully would reference; I tried to look around for previous code without success.Pulver
@zain I too was surprised to see the added activity but since you're unaware yourself, I would reshare the src to your email again so you could look into it, I'm pretty sure it's just a few things were out of place. I appreciate your feedback, sorry I'm this late, I was busy for long, please check your emailPestilential
P
1

So, the current navigation in summary would be:

HomeActivity 
    MainFragment
        BottomNavigationView navGraph
            FirstFragment
            SecondFragment
            ThirdFragment  
    Other fragments...  

And you need to:

  • Safely remove the BottomNavigationView
  • Keep only FirstFragment and Get rid of SecondFragment & ThirdFragment

As the MainFragment only hosts the BottomNavigationView; then you can replace it directly with the FirstFragment; so the navigation would be:

HomeActivity 
    FirstFragment
    Other fragments...  

And to do that:

1. In the main navGraph of the HomeActivity:

  • Replace the MainFragment with FirstFragment (copy the FirstFragment section from the BottomNavigationView navGraph to the main navGraph.
  • Refactor the id of the FirstFragment to the one associated with the MainFragment, because this id is utilized in HomeActivity (or you can do the other way by refactoring it to the FirstFragment)

2. In HomeActivity, Replace the MainFragment in below snippet with the FirstFragment:

if (currentFragment instanceof MainFragment) {
    ((MainFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}

So, it'll be:

if (currentFragment instanceof FirstFragment) {
    ((FirstFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}

This is what appears in the shared code; but you'd replace every single occurrence of MainFragment with FirstFragment, and do any needed refactoring.

Now, you can safely remove the MainFragment will all of its descendants, BottomNavigationView, second & third fragments; and their resources (layouts, menus...), or keep them aside if you're planning to reuse them in the future.

Pulver answered 15/9, 2022 at 4:9 Comment(3)
Good day Zain, after the following 1st and 2nd process that you shared, it safely removed the bottom nav view with the fragments as supposed but there's two or more issues: 1. The toolbar for searching cities have disappered and is now displaying "fragment_first" in the search city section(i can no longer search cities) 2. The navigation drawer is malfunctioning(no more back button and crashing) I have sent the pictures to your email, i would appreciate the solved src for easier understanding and to speed the process, or just the solution, thanksPestilential
toolbar for searching cities have disappered: This requires to change the id of the firstFragment to be the same as the previous id of the main fragment in the navGraph (i.e., copy the FirstFragment from the navGraph of the BottomNavigationView, but change its id to main_id .. because if you notice in the HomeActivity you used R.id.main_id in multiple places... Or you can REFACTOR that to first_fragmentPulver
Made the changes, and now it runs like a charm. You're the best!Pestilential
J
1

Are you try this for bottom navigation?

android:visibility="gone"

I do the samething before.

Judah answered 13/9, 2022 at 6:4 Comment(3)
It hid the bottom navigation view but I don't think this Is good for best practices because it made my phone a lot laggy, I was forced to delete the app. And I asked about how to totally remove them and not just hide, so this answer is incompletePestilential
I understand. as i told, i do the same thing before and didn't face with any issue. this is a temporary solution and easy to go back to normal UI.Judah
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Antione
P
1

So, the current navigation in summary would be:

HomeActivity 
    MainFragment
        BottomNavigationView navGraph
            FirstFragment
            SecondFragment
            ThirdFragment  
    Other fragments...  

And you need to:

  • Safely remove the BottomNavigationView
  • Keep only FirstFragment and Get rid of SecondFragment & ThirdFragment

As the MainFragment only hosts the BottomNavigationView; then you can replace it directly with the FirstFragment; so the navigation would be:

HomeActivity 
    FirstFragment
    Other fragments...  

And to do that:

1. In the main navGraph of the HomeActivity:

  • Replace the MainFragment with FirstFragment (copy the FirstFragment section from the BottomNavigationView navGraph to the main navGraph.
  • Refactor the id of the FirstFragment to the one associated with the MainFragment, because this id is utilized in HomeActivity (or you can do the other way by refactoring it to the FirstFragment)

2. In HomeActivity, Replace the MainFragment in below snippet with the FirstFragment:

if (currentFragment instanceof MainFragment) {
    ((MainFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}

So, it'll be:

if (currentFragment instanceof FirstFragment) {
    ((FirstFragment) currentFragment).getWeatherData(textfield.getText().toString().trim());
}

This is what appears in the shared code; but you'd replace every single occurrence of MainFragment with FirstFragment, and do any needed refactoring.

Now, you can safely remove the MainFragment will all of its descendants, BottomNavigationView, second & third fragments; and their resources (layouts, menus...), or keep them aside if you're planning to reuse them in the future.

Pulver answered 15/9, 2022 at 4:9 Comment(3)
Good day Zain, after the following 1st and 2nd process that you shared, it safely removed the bottom nav view with the fragments as supposed but there's two or more issues: 1. The toolbar for searching cities have disappered and is now displaying "fragment_first" in the search city section(i can no longer search cities) 2. The navigation drawer is malfunctioning(no more back button and crashing) I have sent the pictures to your email, i would appreciate the solved src for easier understanding and to speed the process, or just the solution, thanksPestilential
toolbar for searching cities have disappered: This requires to change the id of the firstFragment to be the same as the previous id of the main fragment in the navGraph (i.e., copy the FirstFragment from the navGraph of the BottomNavigationView, but change its id to main_id .. because if you notice in the HomeActivity you used R.id.main_id in multiple places... Or you can REFACTOR that to first_fragmentPulver
Made the changes, and now it runs like a charm. You're the best!Pestilential
S
0
navController.addOnDestinationChangedListener { _, destination, _ ->

 if(destination.id == R.id.first_fragment) {
    // your intro fragment will hide your bottomNavigationView
    bottomNavigationView.visibility = View.GONE
  } else if (destination.id == R.id.second_fragment){
   // your second fragment will show your bottomNavigationView
   bottomNavigationView.visibility = View.VISIBLE
 }
}

You can hide and show according to the relevant destination.

Sollie answered 13/9, 2022 at 6:22 Comment(1)
Okay but remember that I'm trying to totally remove the bottom nav view and fragments and not just hide, I'll only hide if I cannot remove them. Also, you didn't include where this code should be written because I tried entering it in the activity and it didn't workPestilential
C
0

You should write this code in your MainActivity.

navController.addOnDestinationChangedListener { _, destination, _ ->
        when (destination.id) {
            R.id.navigation_order_active,
            R.id.navigation_order_open,
            R.id.navigation_main_more -> binding.navView.isVisible = true

            else -> binding.navView.isVisible = true
        }
    }

So, If you want enable to animate of bottomNavBar's hide/show, you need to add this one line code android:animateLayoutChanges="true" in your parent layout:

<?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"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true">

    <androidx.fragment.app.FragmentContainerView />

    <com.google.android.material.bottomnavigation.BottomNavigationView />

</androidx.constraintlayout.widget.ConstraintLayout>
Coquelicot answered 3/10 at 11:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.