Daniel Daniel
Daniel Daniel

Reputation: 77

Replace fragments in default Android Studio navigation drawer

I am trying to replace home fragment with gallery fragment and vice versa in the default navigation drawer from Android Studio. This is the main class:

package com.example.navdrawer;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import android.view.View;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.navigation.NavigationView;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu;

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
                R.id.nav_tools, R.id.nav_share, R.id.nav_send)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

This is the home fragment class:

import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.example.navdrawer.R;
import com.example.navdrawer.ui.gallery.GalleryFragment;

public class HomeFragment extends Fragment {
    Button button;
    TextView textView = null;
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.fragment_home, container, false);
        textView = root.findViewById(R.id.text_home);
        textView.setText("This is home fragment");
        button = root.findViewById(R.id.home_button);
        return root;
    }
    public void onClick(View v) {
//respond to clicks
        if (v.getId() == R.id.home_button) {
            GalleryFragment frag = new GalleryFragment();
            FragmentManager ft = getFragmentManager();
            FragmentTransaction fragmentTransaction =ft.beginTransaction();
            fragmentTransaction.replace(R.id.home, frag);
            // ft.addToBackStack(null);
            fragmentTransaction.commit();
        }

        }

}

The gallery fragment is simillar with the home fragment:

 package com.example.navdrawer.ui.gallery;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.example.navdrawer.R;
import com.example.navdrawer.ui.home.HomeFragment;

public class GalleryFragment extends Fragment {
    Button button;
    TextView textView = null;
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.fragment_gallery, container, false);
        textView = root.findViewById(R.id.text_gallery);
        textView.setText("This is gallery fragment");
        button = root.findViewById(R.id.gallery_button);
        return root;
    }

    public void onClick(View v) {
//respond to clicks
        if (v.getId() == R.id.gallery_button) {
            HomeFragment frag = new HomeFragment();
            FragmentManager ft = getFragmentManager();
            FragmentTransaction fragmentTransaction =ft.beginTransaction();
            fragmentTransaction.replace(R.id.gallery, frag);
            // ft.addToBackStack(null);
            fragmentTransaction.commit();
        }

    }

}

And I've got this xml for the home fragment, which is simillar with the xml from the gallery fragment:

 <?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:id="@+id/scrollView2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <RelativeLayout
        android:id="@+id/home"
        android:screenOrientation="portrait"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/text_home"
                android:layout_marginTop="50dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" />

        <Button
            android:id="@+id/home_button"
            android:layout_centerHorizontal="true"
            android:layout_below="@+id/text_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/replace1" />


    </RelativeLayout>
</ScrollView>

I don't know why it's not working.

Upvotes: 1

Views: 2896

Answers (2)

Daniel Daniel
Daniel Daniel

Reputation: 77

I've found the answer from this post: link For navigation between fragments, all I had to do was to implement this method in the "onCreateView" function:

button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.nav_gallery, null));

Another method is:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Navigation.findNavController(view).navigate(R.id.nav_gallery);
            }
        });

I still don't know how to navigate between fragments using a conditional "if, else" statement, inside a function, maybe this will imply another type of "action listening"...

Upvotes: 5

ianhanniballake
ianhanniballake

Reputation: 199805

The default template uses the Navigation component which means you don't manually do FragmentTransactions. Instead, as per the documentation, you'd add your GalleryFragment to your navigation XML file (under res/navigation) then call navigate() to go to that destination, replacing the screen you're currently on.

Upvotes: 1

Related Questions