I have been struggling with this since yesterday morning. I am familiar with C++(just stating I do have programming experience). I am learning android programming. When my app starts it brings up an activity. I suspect it is
setContentView(R.layout.activity_main);
In my navigation drawer, I have 3 items. One is called "Piggy Bank" which is suppose to be the navigation home. "Graph" and "Settings" are the other 2. I want it so when someone clicks on "Piggy Bank" in the navigation drawer it goes back to the original screen that loads when the program starts. This needs to be done without creating a new activity, the data in the home screen is important and should not be cleared when going back to it. It should contain the data that was left there.
Here is what I tried
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
android.app.FragmentManager fragmentManager = getFragmentManager();
if (id == R.id.nav_PiggyBank) {
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// getActionBar().setDisplayHomeAsUpEnabled(true);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
} else if (id == R.id.nav_Graph) {
fragmentManager.beginTransaction()
.replace(R.id.content_frame
, new Graph())
.commit();
} else if (id == R.id.nav_Settings) {
fragmentManager.beginTransaction()
.replace(R.id.content_frame
, new UserSettings())
.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
here is my activity_main
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
You should place everything that's inside your if (id == R.id.nav_PiggyBank) { ... } case in your onCreateMethod of the activity. Inside the if-case you should tell the FragmentManager to replace the current fragment container (R.id.content_frame) with your PiggyBankFragment...like you've done in the both other if-else cases ;-)
Update:
If you want to use the NavigationDrawer I recommend to use multiple fragments with content and just one activity, that holds the fragment container and your navigation drawer. So the structure of your app looks like this:
1. You create your PiggyBankActivity which contains the fragment_container and the navigation drawer. Nothing else - no piggy bank content
2. You create a PiggyBankFragment which contains all of the content you want to display on this "home" page
3. You use FragmentManager and FragmentTransactions in onNavigationItemSelected to replace the fragments and show the desired content.
You can refer to this documentation: https://developer.android.com/training/implementing-navigation/nav-drawer.html
or this example
https://www.simplifiedcoding.net/android-navigation-drawer-example-using-fragments/
;-)
Related
hi i have navigation drawer in my android application in the main activity java class and this is the code
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
//add this line to display menu1 when the activity is loaded
displaySelectedScreen(R.id.nav_menu1);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
private void displaySelectedScreen(int itemId) {
//creating fragment object
Fragment fragment = null;
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
//initializing the fragment object which is selected
switch (itemId) {
case R.id.nav_menu1:
fragment = new gallary();
break;
case R.id.nav_menu2:
fragment = new about();
break;
case R.id.nav_menu3:
fragment = new contact();
break;
}
//replacing the fragment
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
drawer.closeDrawer(GravityCompat.START);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
//calling the method displayselectedscreen and passing the id of selected menu
displaySelectedScreen(item.getItemId());
//make this method blank
return true;
}
}
and this is the main activity xml code
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
so i want to add some content such an images and texts to main activity xml page of the app but when i add it in main content of navigation it looks good and everything okay but when i click on for example gallary fragment from the navigation drawer it took me to new page which has the content that i put in gallary xml but the problem is the content of main activity appear too with all fragment pages that i click from navigation drawer
how can i make the content of each fragment appear without the content of main activity
anyone understand me ? #_#
I would suggest you to not to use any element other than navigationView and the fragment which will show up your screen for the navigationDrawer items, because you if clicked on some item you will be redirected to that page but later if you ever wanted to get back to that mainactivity page it becomes nearly impossible.Either you restart the activity or try some complex method to achieve that.
Instead you should use fragments. You can call a default fragment which will be loaded on opening the app in onResume() method. This fragment should also be available in navigation item for later references.You can do it like this:
fragment = new YourFragment();
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.contentfragment,fragment).commitNow();
But if you still wanted to do so, you can set the elements of the mainactivity to visibility to gone. I don't know if this method will work.
This should be set on navigation item click
[your_element].setVisibility(View.GONE);
You fragments are overlapping each other.
Just make sure you remove the previous fragment before adding a new fragment when selecting a navigation item from the drawer:
FragmentManager fm = getSupportFragmentManager();
fm.bginTransaction()
.remove(oldFragment)
.add(newFragment)
.commit();
I have two navigation views in my Activity. One enters from the right and the other enters from the left.
In the navigtionview that enters from from the left, different fragments are started when when the items are clicked. And also, this same navigationview has menu items which is common to all the launched fragments. I don't have any problem with this one.
Now, the navigationview that enters from the right has menu items which are only peculiar to the particular fragment started when the first item in the left entering navigationview is clicked. What this means is that, when you clicked the first item in the left entering navigation drawer, a fragament is started, and items in the right entering navigationview has items related to this fragment.
So, this right navigationview is stared when a menuitem in the toolbar is clicked. And this menu item is not visible when other fragments (apart from the aforementioned) is in view.
The problem I have is that, even when the right entering navigationview cannot be launched through the menuitem in other fragments, it can still be started by sliding the right edge of the screen. So I want to totally disable the sliding feature of this right entering navigationview, so it can only be launched when the menu item is clicked.
Codes
activity_main
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
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"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="false"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"/>
<android.support.design.widget.NavigationView
android:id="#+id/cat_nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="false">
/** This navigationview enters from the right, I start a fragment with framelayout below.
The fragment contains a recyclerview **/
<FrameLayout
android:id="#+id/transport_cat_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
Snippets of MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
#Override
public void onDrawerClosed(View v){
super.onDrawerClosed(v);
}
#Override
public void onDrawerOpened(View v) {
super.onDrawerOpened(v);
}
};
drawer.addDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (drawer.isDrawerOpen(GravityCompat.END)) {
drawer.closeDrawer(GravityCompat.END);
} else {
super.onBackPressed();
}
}
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
#Override
public void onDrawerClosed(View v){
super.onDrawerClosed(v);
}
#Override
public void onDrawerOpened(View v) {
super.onDrawerOpened(v);
}
};
drawer.addDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
navigationView.setNavigationItemSelectedListener(this);
Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
Fragment fragment;
if (id == R.id.menu_cars) {
fragment = new CarsFragment();
startCarsFrag() //Method to start CarsFragment()
//The right entering drawer should only be enabled for this fragment
}
if (id == R.id.menu_trains) {
fragment = new TrainsFragment();
startTrainFrag() //Method to start TrainsFragment
}
if (id == R.id.menu_lorries) {
fragment = new LorriesFragment();
startLorriesFrag() //Method to start LorriesFragment
}
if (drawer != null) {
drawer.closeDrawer(GravityCompat.START);
}
return true;
}
The DrawerLayout#setDrawerLockMode() method is what you're looking for. When locked, a drawer View cannot be dragged open/closed, though it will still respond to the openDrawer() and closeDrawer*() methods.
Since you're using two drawers, and want to lock only the one, you'll need to call the method with a second argument to indicate which drawer to lock/unlock. For example, to lock your secondary drawer closed:
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, GravityCompat.END);
I tried to create one simple app with Drawer Menu. I created a project with Android Studio and select Navigation Drawer Layout. I'm trying to hide navigation drawer header and put it on toolbar... I found the way to put on toolbar but I can't find hide RED part of header in picture. Can you help me please.
Here is my layout page xml codes
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:layout_marginTop="?attr/actionBarSize" //With this code i put menu under toolbar
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
Here is my MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
FragmentManager fragmentManager = getFragmentManager();
if (id == R.id.nav_first_layout) {
fragmentManager.beginTransaction().replace(R.id.content_frame,new FirstFragment()).commit();
} else if (id == R.id.nav_second_layout) {
fragmentManager.beginTransaction().replace(R.id.content_frame,new SecondFragment()).commit();
} else if (id == R.id.nav_third_layout) {
fragmentManager.beginTransaction().replace(R.id.content_frame,new ThirdFragment()).commit();
} else if (id == R.id.nav_home) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
How can I hide that red part??
Set fitsystemwindow=false under android.support.design.widget.NavigationView in xml.
Use this In your MainActivity if you want to do it programmatically else see the second option below.
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View header = navigationView.getHeaderView(0);
header.setVisibility(View.GONE);
OR if you not wanna use that and want to accomplish this via xml then check below option.
In your xml file of main activity you should have NavigationView like this
<android.support.design.widget.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/navigation_view_I"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_menu"
app:headerLayout="#layout/navigation_drawer_header">
Remove last line from the above NavigationView which is this
app:headerLayout="#layout/navigation_drawer_header"
Add below code inside of onCreateView() of NavigationDrawer Fragment class
View headerView= LayoutInflater.from(this).inflate(R.layout.drawer_header, null);
navigationView.addHeaderView(headerView);
navigationView.getHeaderView(0).setVisibility(View.GONE);
Note:- relace R.layout.drawer_header by your header view resource file.
I have made one Activity with a NavigationView (opened with a toggle button):
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
private DrawerLayout drawer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.app_name, R.string.app_name);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null) {
navigationView.setNavigationItemSelectedListener(this);
navigationView.setItemIconTintList(null);
navigationView.getMenu().getItem(0).setChecked(true);
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer != null) {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment = null;
Class fragmentClass;
fragmentClass = FirstFragment.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
break;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.layout, fragment).commit();
item.setChecked(true);
setTitle(item.getTitle());
drawer.closeDrawers();
return true;
}
}
When I select one item of NavigationView it starts a Fragment:
public class FirstFragment extends Fragment {
private View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_layout, container, false);
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) view.findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
getActivity(), drawer, toolbar, R.string.app_name, R.string.app_name);
drawer.addDrawerListener(toggle);
toggle.syncState();
return view;
}
}
Problem:
When I select the button ≡ to open the NavigationView inside Fragment and I select the items it doesn't open FirstFragment.
If I swipe from the left to open NavigationView inside Fragment and I select the items it opens FirstFragment.
How can I reuse onNavigationItemSelected from MyActivity on FirstFragment?
Edit:
This is the acitivity_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ddffff"
android:fitsSystemWindows="true">
<LinearLayout
android:id="#+id/list_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
//FragmentLayout
<RelativeLayout
android:id="#+id/layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<include
android:id="#+id/bar"
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
...
</RelativeLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ddffff"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
The root cause of this is that you're using the same layout in your Fragment as you are in the Activity, and the Toolbar is inside the container ViewGroup you transact the Fragment into. Once a Fragment has been loaded with its own DrawerLayout and Toolbar, it covers the Activity's Toolbar, so nothing looks out of the ordinary. However, the toggle in the Fragment is operating the drawer in the Fragment, and that drawer is a second NavigationView that hasn't been setup like the one in the Activity, so nothing happens when you click on the drawer opened with the toggle. But, if you drag the drawer open, the one that's opening is actually the Activity's drawer, and that NavigationView was setup correctly, so clicking on that one works as expected.
The first correction is to move the Toolbar - its <include> element, that is - to outside of the RelativeLayout you're using as the Fragment container. This will prevent the Activity's Toolbar from being obscured when Fragments are loaded.
The second step is to define separate, different layout XML files for the Fragments. You don't want to use the same layout in the Fragments as you are in the Activity, mostly because that's probably not really what you intend, and also because you really don't want to have multiple, redundant DrawerLayouts, Toolbars, and NavigationViews, which can cause problems, as you've seen.
Please, explain to me... I have Navigation Drawer in my Activity and it syncs with Toolbar (like ActionBar). Activity has few fragments and in different fragments I need to use different AppBar modes (parallax in one, simple in another). So, I think that I should set CoordinatorLayout in each frament with AppBar and content.
But how I can replace last toolbar on new to save synchronization with Drawer? Or it's wrong way and I need make it some else?
Not sure if my approach is good, but I tried to add this public method to my activity:
public void setToolbar(Toolbar toolbar) {
if(toolbar != null) {
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
} else {
drawer.setDrawerListener(null);
}
}
and I added this in all fragments:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((MainActivity)getActivity()).setToolbar(toolbar);
}
#Override
public void onDestroyView() {
((MainActivity)getActivity()).setToolbar(null);
super.onDestroyView();
}
It's working fine, but I'm not sure if it may cause a memory leak or any other performance issue. Maybe someone can help with it?
You can access main DrawerLayout from each Fragment just like the following code:
AppCompatActivity actionBar = (AppCompatActivity) getActivity();
actionBar.setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) actionBar.findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
getActivity(), drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
If you want to use appbar(toolbar) that you specified in navigation drawer in different fragments with, for example different options menu items, you could make a public method in Main Activity where you specified your navigation drawer logic.
public void setToolbar(Toolbar toolbar, String title){
AppCompatActivity actionBar = this;
actionBar.setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout)actionBar.findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toogle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
drawer.addDrawerListener(toogle);
toogle.setDrawerIndicatorEnabled(true);
toogle.syncState();
if(toolbar != null)
toolbar.setTitle(title);
}
Now you can use this method in your fragments to access the main toolbar and override it with your custom title, options menu...
You can do this by creating a new toolbar variable in your fragment and then inflate it in onCreateView() method like this
toolbarFragment = (Toolbar)getActivity().findViewById(R.id.toolbar);
R.id.toolbar is the id of a toolbar that you specified in your layout file and it is the same id that you used in your main activity for the main toolbar.
Now you can call the method setToolbar(Toolbar toolbar, String title) in fragment like this
((MainActivity)getActivity()).setToolbar(toolbarFragment, "Some title");
If you want to use options menu for this fragment you have to call
setHasOptionsMenu(true);
in fragments onCreate() or onCreateView() methods. After that you can override method onCreateOptionsMenu() like this
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.custom_menu1, menu);
}
You can repeat this procedure for other fragments in your navigation drawer as well. Although it worked for me, I don't know if this violates activities or fragments lifecycle or causes memory leeks.
I have the same problem. I wanted to add CollapsingToolbar only in the main fragment. By removing the toolbar from Activity, I lost the hamburger button and the connection to drawerLayout. To solve this problem, I didn't delete the Toolbar in activity and made it transparent. And for each fragment, I created my own custom toolbar. In the end, I have a hamburger button linked to the Drawer and a well-functioning CollapsingToolbar. I know it's a crutch. But I couldn't find another way
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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=".activity.MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include
android:id="#+id/include"
layout="#layout/content_main"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
To make the AppBar completely invisible, I added
AppBarLayout appBarLayout = findViewById(R.id.appbar);
appBarLayout.setOutlineProvider(null);
This works for Android with sdk version 21.
If you are using DrawerLayout and NavigationView for your navigation drawer, best solution according to me would be to use individual DrawerLayout for each of the fragment layouts and use the AppBarLayout in the body of the DrawerLayout differently for each of the fragments.