Fragment Navigation Drawer - nhtechip/android-bootstrap GitHub Wiki
In Common Navigation Paradigms cliffnotes, we discuss the various navigational structures available within Android applications. One of the most flexible is the Navigation Drawer. The fully custom navigation drawer is totally managed by the user and can be read about on the creating the navigation drawer docs.
This guide instead explains how to setup a basic drawer filled with navigation items that switch different fragments into the content area. In this way, you can define multiple fragments, and then define the list of options which will display in the drawers items list. Each item when clicked will switch the relevant fragment into the activity's container view.
Next, be sure to download the drawer image assets necessary and add the images into each of your drawable folders.
Verify that you have the latest support-v4.jar file. These JAR files do get updated between API versions. If you get NoClassDefErrors even though you've added the file, you may be missing the DrawerLayout class and other dependencies that were incorporated in API version 13. For best results, included the latest support-v4.jar from the most recent API version.
You also need to setup a view that will represent the individual drawer item in a layout file such as res/layout/drawer_nav_item.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textColor="#111"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"/>Then in your res/values/strings.xml add the following:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
</resources>First, let's define our FragmentNavigationDrawer.java file by copying the text from the linked gist.
Next, you need to define your fragments that will be displayed within the drawer. These can be any support fragments you define within your application.
Next, let's setup a basic navigation drawer based on the following layout file which has the entire drawer setup in res/layout/activity_main.xml:
<com.codepath.examples.navdrawerdemo.FragmentNavigationDrawer
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/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="@+id/lvDrawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/darker_gray"
android:dividerHeight="0dp"
android:background="@android:color/background_light"
/>
</com.codepath.examples.navdrawerdemo.FragmentNavigationDrawer>Now, let's setup the drawer in our activity:
public class MainActivity extends FragmentActivity {
private FragmentNavigationDrawer dlDrawer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find our drawer view
dlDrawer = (FragmentNavigationDrawer) findViewById(R.id.drawer_layout);
// Setup drawer view
dlDrawer.setupDrawerConfiguration((ListView) findViewById(R.id.lvDrawer),
R.layout.drawer_nav_item, R.id.flContent);
// Add nav items
dlDrawer.addNavItem("First", "First Fragment", FirstFragment.class);
dlDrawer.addNavItem("Second", "Second Fragment", SecondFragment.class);
dlDrawer.addNavItem("Third", "Third Fragment", ThirdFragment.class);
// Select default
if (savedInstanceState == null) {
dlDrawer.selectDrawerItem(0);
}
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content
if (dlDrawer.isDrawerOpen()) {
menu.findItem(R.id.mi_test).setVisible(false);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (dlDrawer.getDrawerToggle().onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
dlDrawer.getDrawerToggle().syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggles
dlDrawer.getDrawerToggle().onConfigurationChanged(newConfig);
}
}Now if you run your application, you should see the navigation drawer and be able to select between your fragments. For a more in-depth look at a navigation drawer with icons and sections, check out this detailed navigation drawer tutorial. You might also want to check out this drawer tutorial from AndroidHive.
Although many navigation drawer examples show how fragments can be used with the navigation drawer, you can also use a RelativeLayout/LinearLayout if you wish to use the drawer as an overlay to your currently displayed Activity.
Instead of <FrameLayout> you can substitute that for a <LinearLayout>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawer_layout">
<LinearLayout
android:id="@+id/content_frame"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>Instead of this:
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();You can instead use the LinearLayout container to inflate the Activity directly:
LayoutInflater inflater = getLayoutInflater();
LinearLayout container = (LinearLayout) findViewById(R.id.content_frame);
inflater.inflate(R.layout.activity_main, container);