How to hide navigation drawer when opening certain fragment?
Asked Answered
I

3

13

I'm pretty new in android development. I want to hide navigation drawer when user is not logged in. So basically, it will shown login fragment (better in full screen like Facebook android). And if user already logged in, navigation drawer will always shown.

MainActivity.java

public class MainActivity extends AppCompatActivity {

private DrawerLayout navDrawerLayout;
private Toolbar toolbar;
private ActionBarDrawerToggle navDrawerToggle;

private SharedPreferences pref;

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

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    navDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    // Find our drawer view
    NavigationView navDrawerView = (NavigationView) findViewById(R.id.navdrawer_view);
    // Setup drawer view
    setupDrawerContent(navDrawerView);

    navDrawerToggle = setupDrawerToggle();

    pref = getPreferences(0);
    initFirstFrame();
}

private ActionBarDrawerToggle setupDrawerToggle() {
    return new ActionBarDrawerToggle(this, navDrawerLayout, toolbar, R.string.drawer_open,  R.string.drawer_close);
}

private void setupDrawerContent(NavigationView navDrawerView) {
    navDrawerView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    selectDrawerItem(menuItem);
                    return true;
                }


            });
}

public void selectDrawerItem(MenuItem menuItem) {
    // Create a new fragment and specify the fragment to show based on nav item clicked
    Fragment fragment = null;
    Class fragmentClass;
    switch(menuItem.getItemId()) {
        case R.id.events:
            fragmentClass = EventsFragment.class;
            break;
        case R.id.pengumuman:
            fragmentClass = NewsFragment.class;
            break;
        case R.id.edit_profil:
            fragmentClass = ProfileFragment.class;
            break;
        default:
            fragmentClass = EventsFragment.class;
    }

    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }

    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.frame_content, fragment).commit();

    // Highlight the selected item has been done by NavigationView
    menuItem.setChecked(true);
    // Set action bar title
    setTitle(menuItem.getTitle());
    // Close the navigation drawer
    navDrawerLayout.closeDrawers();
}

private void initFirstFrame(){
    Fragment fragment;
    if(pref.getBoolean(Constants.IS_LOGGED_IN,false)){
        fragment = new ProfileFragment();
    }else {
        fragment = new LoginFragment();
        // in this login fragment, navdrawer should be invisible, the toolbar too I guess
    }

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.frame_content,fragment);
    fragmentTransaction.commit();
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    return navDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}

// 'onPostCreate' called when activity start-up is complete after 'onStart()'
// NOTE! Make sure to override the method with only a single 'Bundle' argument
@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred
    navDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggles
    navDrawerToggle.onConfigurationChanged(newConfig);
}

}
Issue answered 18/7, 2016 at 9:20 Comment(4)
Use a LoginActivity and the MainActivity, where the navigation drawer resides and Login is without it. This is how I did it.Worked
@Worked if I did that, then how to parse every inputed data by user to my MainActivity? As you see, I have ProfileFragment, that user can edit e-mail, password, etc. Sorry, I'm beginner and less clue with intent thing.Issue
You need to learn, do not avoid doing the stuff a certain way because you are unfamiliar with them. You can find basically anything online. I'd suggest searching for a tutorial online about logging in, as well as looking and studying a template in Android studio called "Login Activity".Worked
Best way to communicate between fragments and activities is through interfaces. It helps code re-use and can be used inter-fragments as well.Check inter Fragment communication in google. My answer will hint you in the direction though :)Gotland
G
23

Define an interface say DrawerLocker:

interface DrawerLocker{
   public void setDrawerLocked(boolean shouldLock);
}

Implement this interface in your activity which contains the NavigationDrawer and override this method.

class YourActivity implements DrawerLocker{
...
...
public void setDrawerLocked(boolean enabled){
    if(enabled){
        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    }else{
        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    }

}

Now in your Fragment's onCreateView, call this method like:

 ((DrawerLocker)getActivity()).setDrawerLocked(true);

In your Fragment's onDestroyView, re enable the drawer layout:

((DrawerLocker)getActivity()).setDrawerLocked(false);
Gotland answered 18/7, 2016 at 9:28 Comment(5)
Note: if you decide to re-use this fragment on another activity, make sure to implement the interface and if that activity does not have a navigation drawer, just implement a blank methodGotland
Hi, sorry that was a typo: its a method call -> getActivity() . glad it helped youGotland
@Gotland Wow you are great man...+1000 thank u so much dude thanks thanks thansk...Matthiew
Any time buddy :)Gotland
This answer didn't work for me, either. But this did: https://mcmap.net/q/904344/-remove-android-toolbar-navigation-drawer-optionDalhousie
H
3

This code in activity onCreate method will block drawer when you will have more than one fragment in stack:

 getSupportFragmentManager().addOnBackStackChangedListener(() -> {
        if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        } else {
            drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        }
    });
Hyperemia answered 24/11, 2017 at 12:52 Comment(0)
I
1

This is all you need, check your destinations in if condition where you don't want the drawer to be

Single activity architecture, put below code in activity onCreate

private fun changeDrawerState() {
    val navHostFragment = supportFragmentManager
        .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val drawer = findViewById<DrawerLayout>(R.id.drawer_layout)
    navHostFragment.navController.addOnDestinationChangedListener(listener = { _, destination, _ ->
        //set in case app asked for verify auth, signIn page drawer will be locked
        if (destination.id== R.id.signInFragment) {
            drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
        } else if (drawer.getDrawerLockMode(GravityCompat.START) != DrawerLayout.LOCK_MODE_UNLOCKED) {
            drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
        }
    })
}

GravityCompat.START based on your drawer open direction

Immediate answered 24/4, 2022 at 4:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.