I have a DrawerLayout with three sections: one of them is a two pane layout implemented like the android studio template, so two fragment, one next to the other, contained in a LinearLayout. Here is the layout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:id="@+id/twoPaneLayut"
android:divider="?android:attr/dividerHorizontal"
android:showDividers="middle">
<FrameLayout
android:id="@+id/alarm_list_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/alarm_detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
</FrameLayout>
<ListView
android:id="@+id/left_drawer"
android:layout_width="@dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111" />
Now, the other sections are composed by a single Fragment so I was trying to replace the main content of the external FrameLayout with a FragmentTransaction.
The problem is that the inner LinearLayout obviously is not removed.
So what is the best strategy to follow? removing programmatically the LinearLayout? Setting its visibilty to GONE?
FrameLayout
will not work with weightSum
it is by design meant to fill up your layout. Try using a LinearLayout
or RelativeLayout
instead.
Secondly, when it comes to swapping all your content, you have a few options.
Option 1
Use one FrameLayout
, for your 2 panel layout create a Fragment
that contains 2 Fragments. Yes, you can have Fragment
s within Fragment
s.
In this scenario, your Activity
's layout will look more like the implementation that Google recommends and it is your fragments layout that will contain the 2 panel layout.
Option 2
You can swap out one of the LinearLayout
s for your fragment and hide the other LinearLayout
. There is no reason you can only swap a FrameLayout
for a fragment, you should be able to swap out a LinearLayout
for a Fragment
as well.
Option 3
The DrawerLayout
implementation is just a recommendation. You can move the layout for your drawer into a fragment and use a different Activity
for your different layouts. To be clear, instead of a ListView
for your drawer, you will have a fragment. In this scenario, put all the code to add the toggle controls in a helper class so you can easily reuse it, your drawer view will be in a fragment and hence it will be easier to include in multiple activities.
I've included an example of how to do this, because you need to wrap your navigation drawer fragment in a frame layout and give the frame layout the layout_gravity
property otherwise the fragment will fill up the whole screen and not close.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- The main content view -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<FrameLayout
android:id="@+id/nav_drawer_container"
android:layout_gravity="start"
android:layout_width="240dp"
android:layout_height="match_parent" >
<fragment
android:id="@+id/nav_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
class="com.alimuzaffar.myapp.fragment.NavigationMenuFragment" />
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
The code for the toggle helper can be something like the setupNavigationDrawer()
method below. Just call this code from the onCreate()
of any activity you want to have the navigation drawer.
public static void setupNavigationDrawer() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
if (mDrawerLayout != null) {
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
@Override
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(mTitle);
supportInvalidateOptionsMenu(); // creates call
// to
// onPrepareOptionsMenu()
}
@Override
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle("");
supportInvalidateOptionsMenu(); // creates call
// to
// onPrepareOptionsMenu()
}
};
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
}