1 package ${packageName};
3 <#if appCompat>import android.support.v7.app.ActionBarActivity;</#if>
4 import android.app.Activity;
5 import android.<#if appCompat>support.v7.</#if>app.ActionBar;
6 import android.<#if appCompat>support.v4.</#if>app.Fragment;
7 import android.support.v4.app.ActionBarDrawerToggle;
8 import android.support.v4.view.GravityCompat;
9 import android.support.v4.widget.DrawerLayout;
10 import android.content.SharedPreferences;
11 import android.content.res.Configuration;
12 import android.os.Bundle;
13 import android.preference.PreferenceManager;
14 import android.view.LayoutInflater;
15 import android.view.Menu;
16 import android.view.MenuInflater;
17 import android.view.MenuItem;
18 import android.view.View;
19 import android.view.ViewGroup;
20 import android.widget.AdapterView;
21 import android.widget.ArrayAdapter;
22 import android.widget.ListView;
23 import android.widget.Toast;
26 * Fragment used for managing interactions for and presentation of a navigation drawer.
27 * See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
28 * design guidelines</a> for a complete explanation of the behaviors implemented here.
30 public class NavigationDrawerFragment extends Fragment {
33 * Remember the position of the selected item.
35 private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
38 * Per the design guidelines, you should show the drawer on launch until the user manually
39 * expands it. This shared preference tracks this.
41 private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
44 * A pointer to the current callbacks instance (the Activity).
46 private NavigationDrawerCallbacks mCallbacks;
49 * Helper component that ties the action bar to the navigation drawer.
51 private ActionBarDrawerToggle mDrawerToggle;
53 private DrawerLayout mDrawerLayout;
54 private ListView mDrawerListView;
55 private View mFragmentContainerView;
57 private int mCurrentSelectedPosition = 0;
58 private boolean mFromSavedInstanceState;
59 private boolean mUserLearnedDrawer;
61 public NavigationDrawerFragment() {
65 public void onCreate(Bundle savedInstanceState) {
66 super.onCreate(savedInstanceState);
68 // Read in the flag indicating whether or not the user has demonstrated awareness of the
69 // drawer. See PREF_USER_LEARNED_DRAWER for details.
70 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
71 mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
73 if (savedInstanceState != null) {
74 mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
75 mFromSavedInstanceState = true;
78 // Select either the default item (0) or the last selected item.
79 selectItem(mCurrentSelectedPosition);
83 public void onActivityCreated (Bundle savedInstanceState) {
84 super.onActivityCreated(savedInstanceState);
85 // Indicate that this fragment would like to influence the set of actions in the action bar.
86 setHasOptionsMenu(true);
90 public View onCreateView(LayoutInflater inflater, ViewGroup container,
91 Bundle savedInstanceState) {
92 mDrawerListView = (ListView) inflater.inflate(
93 R.layout.${navigationDrawerLayout}, container, false);
94 mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
96 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
100 mDrawerListView.setAdapter(new ArrayAdapter<String>(
101 getActionBar().getThemedContext(),
102 android.R.layout.simple_list_item_<#if minApiLevel gte 11>activated_</#if>1,
105 getString(R.string.title_section1),
106 getString(R.string.title_section2),
107 getString(R.string.title_section3),
109 mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
110 return mDrawerListView;
113 public boolean isDrawerOpen() {
114 return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
118 * Users of this fragment must call this method to set up the navigation drawer interactions.
120 * @param fragmentId The android:id of this fragment in its activity's layout.
121 * @param drawerLayout The DrawerLayout containing this fragment's UI.
123 public void setUp(int fragmentId, DrawerLayout drawerLayout) {
124 mFragmentContainerView = getActivity().findViewById(fragmentId);
125 mDrawerLayout = drawerLayout;
127 // set a custom shadow that overlays the main content when the drawer opens
128 mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
129 // set up the drawer's list view with items and click listener
131 ActionBar actionBar = getActionBar();
132 actionBar.setDisplayHomeAsUpEnabled(true);
133 actionBar.setHomeButtonEnabled(true);
135 // ActionBarDrawerToggle ties together the the proper interactions
136 // between the navigation drawer and the action bar app icon.
137 mDrawerToggle = new ActionBarDrawerToggle(
138 getActivity(), /* host Activity */
139 mDrawerLayout, /* DrawerLayout object */
140 R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
141 R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
142 R.string.navigation_drawer_close /* "close drawer" description for accessibility */
145 public void onDrawerClosed(View drawerView) {
146 super.onDrawerClosed(drawerView);
151 getActivity().${appCompat?string('supportInvalidate','invalidate')}OptionsMenu(); // calls onPrepareOptionsMenu()
155 public void onDrawerOpened(View drawerView) {
156 super.onDrawerOpened(drawerView);
161 if (!mUserLearnedDrawer) {
162 // The user manually opened the drawer; store this flag to prevent auto-showing
163 // the navigation drawer automatically in the future.
164 mUserLearnedDrawer = true;
165 SharedPreferences sp = PreferenceManager
166 .getDefaultSharedPreferences(getActivity());
167 sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).${(minApiLevel gte 9)?string('apply','commit')}();
170 getActivity().${appCompat?string('supportInvalidate','invalidate')}OptionsMenu(); // calls onPrepareOptionsMenu()
174 // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
175 // per the navigation drawer design guidelines.
176 if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
177 mDrawerLayout.openDrawer(mFragmentContainerView);
180 // Defer code dependent on restoration of previous instance state.
181 mDrawerLayout.post(new Runnable() {
184 mDrawerToggle.syncState();
188 mDrawerLayout.setDrawerListener(mDrawerToggle);
191 private void selectItem(int position) {
192 mCurrentSelectedPosition = position;
193 if (mDrawerListView != null) {
194 mDrawerListView.setItemChecked(position, true);
196 if (mDrawerLayout != null) {
197 mDrawerLayout.closeDrawer(mFragmentContainerView);
199 if (mCallbacks != null) {
200 mCallbacks.onNavigationDrawerItemSelected(position);
205 public void onAttach(Activity activity) {
206 super.onAttach(activity);
208 mCallbacks = (NavigationDrawerCallbacks) activity;
209 } catch (ClassCastException e) {
210 throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
215 public void onDetach() {
221 public void onSaveInstanceState(Bundle outState) {
222 super.onSaveInstanceState(outState);
223 outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
227 public void onConfigurationChanged(Configuration newConfig) {
228 super.onConfigurationChanged(newConfig);
229 // Forward the new configuration the drawer toggle component.
230 mDrawerToggle.onConfigurationChanged(newConfig);
234 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
235 // If the drawer is open, show the global app actions in the action bar. See also
236 // showGlobalContextActionBar, which controls the top-left area of the action bar.
237 if (mDrawerLayout != null && isDrawerOpen()) {
238 inflater.inflate(R.menu.global, menu);
239 showGlobalContextActionBar();
241 super.onCreateOptionsMenu(menu, inflater);
245 public boolean onOptionsItemSelected(MenuItem item) {
246 if (mDrawerToggle.onOptionsItemSelected(item)) {
250 if (item.getItemId() == R.id.action_example) {
251 Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
255 return super.onOptionsItemSelected(item);
259 * Per the navigation drawer design guidelines, updates the action bar to show the global app
260 * 'context', rather than just what's in the current screen.
262 private void showGlobalContextActionBar() {
263 ActionBar actionBar = getActionBar();
264 actionBar.setDisplayShowTitleEnabled(true);
265 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
266 actionBar.setTitle(R.string.app_name);
269 private ActionBar getActionBar() {
270 return <#if appCompat>((ActionBarActivity) getActivity()).getSupportActionBar();<#else>getActivity().getActionBar();</#if>
274 * Callbacks interface that all activities using this fragment must implement.
276 public static interface NavigationDrawerCallbacks {
278 * Called when an item in the navigation drawer is selected.
280 void onNavigationDrawerItemSelected(int position);