Please, explain to me... I have Navigation Drawer in my Activity
and it syncs with Toolbar
(like ActionBar
). Activity has few fragment
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();
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?
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 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);
}
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.
setToolbar(Toolbar toolbar, String title)
in fragment like this
((MainActivity)getActivity()).setToolbar(toolbarFragment, "Some title");
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.
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.