Sai
Sai

Reputation: 15718

How to disable or hide a Drawer Layout from Fragment Android

I have 10 different fragments in my application. I need to hide Navigation drawer (Drawer Layout) in few fragments, how can I access Drawer Layout from a fragment and hide it? I know we need to use in activity mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); but how to do it in fragments?

Upvotes: 8

Views: 10403

Answers (7)

Dezo
Dezo

Reputation: 871

KOTLIN SOLUTION WITH NAVIGATION COMPONENT:

If you use a navigation component (one main activity with multiple fragment destinations) then you need to use addOnDestinationChangedListener to handle which fragment will you show and on which will hide your navigation view inside drawer layout.

Here you can see how to start with the navigation component and here is about the setDrawerLockMode method.

So your code will look something like this:

 val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
 val navController = findNavController(R.id.nav_host_fragment)
 navController.addOnDestinationChangedListener{_, destination, _ ->

 if (destination.id == R.id.nav_fragment1) {
     drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
     //DRAWER LOCKED IN fragment1
    
 } else if (destination.id == R.id.nav_fragment2) {
           drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
           //DRAWER UNLOCKED IN fragment2
    
 } else {.....
           
 }
 }

This part of the code you can put in the onCreate() method in your MainActivity. The easiest way to make a Navigation Drawer Activity is automatically in your android studio. Just follow File -> New -> Activity -> Navigation Drawer Activity.

Upvotes: 6

Pizzetto
Pizzetto

Reputation: 81

I struggled with it for hours: setting DrawerLayout to lock mode simply didn't work for me. Even following your examples.

Finally I came up with this post

DrawerLayout.setDrawerLockMode won't work if you set layout_gravity e.g. to start|bottom in the NavigationView. Just set it to start or end

Hope this helps someone

Upvotes: 0

Cem Philipp Freimoser
Cem Philipp Freimoser

Reputation: 709

You could do something like this in your Fragment:

private MainActivity main;

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        main = (MainActivity) activity;
    }

You definitely should avoid this!

A mutch better solution would be to use an Interface to communicate between your Main and the Fragment. You will end up with something like this:

public interface MyInterface {
 public void lockDrawer();
 public void unlockDrawer();
}

Main:

public class DetailViewActivity extends AppCompatActivity implements MyInterface {
 @Override
    public void lockDrawer() {         
      mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    }

 @Override
    public void unlockDrawer() {
     mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    }

}

Fragment:

   public class MyFragment extends Fragment {
     private MyInterface myInterface;

     @Override
     public void onAttach(Activity activity) {
      super.onAttach(activity);
       try {
        myInterface = (MyInterface) activity;
           } catch (ClassCastException e) {
              throw new ClassCastException(activity.toString() + " must implement MyInterface");
            }
        }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        myInterface.lockDrawer();
        return inflater.inflate(R.layout.example_fragment, container, false);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        myInterface.unlockDrawer();
    }

}

Why this is the best solution: If you do something like ((HomeActivity) mActivity) you will not be able to reuse your Fragment. There will be a ClassCastException. In order to reuse your Fragment you should use an Interface instead of casting you MainActivity. So every Activity which will use your Frament can simply implement this Interface. Even if there's no DrawerLayout you can use it. So the big effort is reusability.

Upvotes: 16

Sid.The.Biker
Sid.The.Biker

Reputation: 335

You can use this method to lock or unlock the drawer: DrawerLayout.setDrawerLockMode(...). (There are also two other versions of this method to specify a lock mode for specific drawers.) To lock, use DrawerLayout.LOCK_MODE_LOCKED_CLOSED; to unlock, use DrawerLayout.LOCK_MODE_UNLOCKED.

If you are using the ActionBarDrawerToggle, you need to add some extra code to prevent the drawer from opening when they click the ActionBarDrawerToggle if you've locked the drawer.

enter code here
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// check lock mode before passing to ActionBarDrawerToggle
// I assume your drawer is on the left; if not, use Gravity.RIGHT
int lockMode = mDrawer.getDrawerLockMode(Gravity.LEFT);
if (lockMode == DrawerLayout.LOCK_MODE_UNLOCKED &&
        mDrawerToggle.onOptionsItemSelected(item)) {
    return true;
}
// Handle your other action bar items...

return super.onOptionsItemSelected(item);
}

Upvotes: 0

AndroidCoder
AndroidCoder

Reputation: 2735

You can do this by following way -

Write one public method inside your activity as follows -

public void enableDisableDrawer(int mode) {
    if (mDrawerLayout != null) {
        mDrawerLayout.setDrawerLockMode(mode);
    }
}

and then inside fragment's onResume you can call this and change Drawer lock mode as required -

((HomeActivity) mActivity).enableDisableDrawer(DrawerLayout.LOCK_MODE_UNLOCKED);

OR

((HomeActivity) mActivity).enableDisableDrawer(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);

where mActivity is my activity reference.

This way is working for me.

Upvotes: 4

Tamal
Tamal

Reputation: 200

Create two methods in your activity. One for opening the drawer and other for closing it. See below code.

public class MainActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;
    .......

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        .........
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        .........
    }
    public void openNavigationDrawer() {
        mDrawerLayout.openDrawer(Gravity.LEFT);
    }

    public void closeNavigationDrawer() {
        mDrawerLayout.closeDrawer(Gravity.LEFT);
    }

    public void lockNavigationDrawer() {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    }

    public void unLockNavigationDrawer() {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    }
}

Now call the above methods from your fragment like below

((MainActivity)getActivity()).closeNavigationDrawer(); // to close drawer
((MainActivity)getActivity()).openNavigationDrawer(); // to open drawer
((MainActivity)getActivity()).lockNavigationDrawer(); // to lock drawer
((MainActivity)getActivity()).unLockNavigationDrawer(); // to unlock drawer

Upvotes: 1

sud
sud

Reputation: 505

You can use this method to lock or unlock the drawer: DrawerLayout.setDrawerLockMode(...). (There are also two other versions of this method to specify a lock mode for specific drawers.) To lock, use DrawerLayout.LOCK_MODE_LOCKED_CLOSED; to unlock, use DrawerLayout.LOCK_MODE_UNLOCKED.

If you are using the ActionBarDrawerToggle, you need to add some extra code to prevent the drawer from opening when they click the ActionBarDrawerToggle if you've locked the drawer.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // check lock mode before passing to ActionBarDrawerToggle
    // I assume your drawer is on the left; if not, use Gravity.RIGHT
    int lockMode = mDrawer.getDrawerLockMode(Gravity.LEFT);
    if (lockMode == DrawerLayout.LOCK_MODE_UNLOCKED &&
            mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle your other action bar items...

    return super.onOptionsItemSelected(item);
}

refer link for more infolink here

Upvotes: 1

Related Questions