With the new design library there are several new layouts that change a lot how the toolbar can behave if the developer so wishes. Since different fragments have different behaviors and objectives, for example a gallery fragment with a collapsing toolbar showing an important photo, or a fragment without a scrollview that just doesn't need the appbarlayout for hiding the toolbar, having a single toolbar in the activity can prove difficult.
So with this, should I move the toolbar to each fragment? If so, I have to set the supportActionBar each time I show a fragment and also have a reference of the activity in the fragment which nullifies the independent nature of fragments. If I leave the toolbar in the Activity alone, I have to have multiple layouts defined for each type of behavior in each fragment. What would be the best approach?
As for me it sounds too weird to have appbar and toolbar in each fragment. So I've chosen to have single appbar with toolbar in activity.
To solve that issue with CoordinatorLayout you will have to set different behaviour of your FrameLayout
(or any other Layout) that supposed to hold fragments from each fragment that you want to override default behaviour.
Lets assume, that your default behaviour is app:layout_behavior="@string/appbar_scrolling_view_behavior"
Then in your fragment_activity_layout.xml you may have something like that:
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/dashboard_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.Toolbar"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/dashboard_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
And in each fragment you wish not to implement app:layout_behavior="@string/appbar_scrolling_view_behavior"
you will have to override onAttach
and onDetach
methods that will change behaviour of your FrameLayout
:
CoordinatorLayout.Behavior behavior;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(behavior != null)
return;
FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();
behavior = params.getBehavior();
params.setBehavior(null);
}
@Override
public void onDetach() {
super.onDetach();
if(behavior == null)
return;
FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();
params.setBehavior(behavior);
layout.setLayoutParams(params);
behavior = null;
}
After that CoordinatorLayout won't collapse appbar, etc. and will allow fragment layouts to be full-height.
Here's my solution
<!-- Put your fragment inside a Framelayout and set the behavior for this FrameLayout -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- Your fragment -->
<include layout="@layout/content_main" />
</FrameLayout>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
This is a realy good question: should Toolbar
s that need to act like an ActionBar
be kept in a Activity
or a Fragment
? Having searched around different questions and documentation, I couldn't find a solution that covers all cases. It therefore really depends on your situation wich way to go.
Case 1: Toolbar must be ActionBar replacement
If the Toolbar has to behave like a normal ActionBar (or if max 1 fragment is shown from time to time), I think the best/simplest way is to use traditional Activities
with there own Toolbar and put your Fragment in there. This way you don't have to worry about when which Toolbar must be shown.
Changing the ActionBar (-behaviour) from Fragments is also possible, but I would not recommend it, since that forces you to keep track which Fragment changed the ActionBar when. I don't even know if setting the ActionBar can be done multiple times.
Case 2: Each Fragment should have its own (part of) Toolbar
You could also choose to put different stand alone Toolbars in different Fragments, with their own actions. This way you could display different Fragments next to each other - each with their own actions in their Toolbar - and suggest that it is 1 Toolbar (maybe like the Gmail-app, although I am unsure). This however means that you would have to inflate those Toolbars yourself, but it must not be very difficult.
I hope this will help making a choice.
(Sorry if I made any (language-)mistakes)