nivagation drawer

来源:互联网 发布:w10网络连接图标不见了 编辑:程序博客网 时间:2024/06/09 16:35
Navigation Drawer是从屏幕的左侧滑出,显示应用导航的视图,覆盖在主视图上。

Navigation Drawer是Android团对在2013 google IO大会期间更新的Support库(V13)中新加入的重要的功能。

实现现Navigation Drawer需要使用最新支持库(V13)的DrawerLayout。Navigation Drawer的设计指南请参考 

Navigation Drawer design guide,但是当时需要的最低版本14,这就限制了我们的使用,当然可以使用来实现兼容,

这并不是最好的,如今谷歌退出V7来实现兼容低版本,我们不需要额外的其他代码,如果你的sdk更新到22.6.2的话,

在创建一个新的项目的时候,在最后一步创建一个Activity的时候,会让你选择一个主题,其中有一项就是

Navigation Drawer,选中然后创建项目。

我们接下来分析一下,项目内容:

1、布局内容

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:id="@+id/drawer_layout"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     tools:context="com.example.androidsampe1.MainActivity" >  
  7.   
  8.     <FrameLayout  
  9.         android:id="@+id/container"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent" />  
  12.   
  13.   
  14.     <fragment  
  15.         android:id="@+id/navigation_drawer"  
  16.         android:name="com.example.androidsampe1.NavigationDrawerFragment"  
  17.         android:layout_width="@dimen/navigation_drawer_width"  
  18.         android:layout_height="match_parent"  
  19.         android:layout_gravity="left" />  
  20.   
  21. </android.support.v4.widget.DrawerLayout>  

DrawerLayout作为跟布局,要求全屏,有两个子布局,第一个是显示内容,第二个是左边抽屉内容,这里是使用一个

fragment,也可以使用其他的View。

主界面:

MainActivity.java

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.androidsampe1;  
  2.   
  3. import android.app.Activity;  
  4. import android.support.v7.app.ActionBarActivity;  
  5. import android.support.v7.app.ActionBar;  
  6. import android.support.v4.app.Fragment;  
  7. import android.support.v4.app.FragmentManager;  
  8. import android.os.Bundle;  
  9. import android.view.LayoutInflater;  
  10. import android.view.Menu;  
  11. import android.view.MenuItem;  
  12. import android.view.View;  
  13. import android.view.ViewGroup;  
  14. import android.support.v4.widget.DrawerLayout;  
  15. import android.widget.TextView;  
  16.   
  17. public class MainActivity extends ActionBarActivity  
  18.         implements NavigationDrawerFragment.NavigationDrawerCallbacks {  
  19.   
  20.     /** 
  21.      * 这个Fragment管理行为、交互和演示导航的抽屉 
  22.      * Fragment managing the behaviors, interactions and presentation of the navigation drawer. 
  23.      */  
  24.     private NavigationDrawerFragment mNavigationDrawerFragment;  
  25.   
  26.     /** 
  27.      * 用来存储上一个屏幕的标题 
  28.      * Used to store the last screen title. For use in {@link #restoreActionBar()}. 
  29.      */  
  30.     private CharSequence mTitle;  
  31.   
  32.     @Override  
  33.     protected void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.activity_main);  
  36.   
  37.         mNavigationDrawerFragment = (NavigationDrawerFragment)  
  38.                 getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);  
  39.         mTitle = getTitle();  
  40.   
  41.         // Set up the drawer. 建立抽屉  
  42.         mNavigationDrawerFragment.setUp(  
  43.                 R.id.navigation_drawer,  
  44.                 (DrawerLayout) findViewById(R.id.drawer_layout));  
  45.     }  
  46.     //这里切换布局的地方,根据position,我们可以选择要替换的fragment  
  47.     @Override  
  48.     public void onNavigationDrawerItemSelected(int position) {  
  49.         // update the main content by replacing fragments  
  50.         FragmentManager fragmentManager = getSupportFragmentManager();  
  51.         fragmentManager.beginTransaction()  
  52.                 .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))  
  53.                 .commit();  
  54.     }  
  55.   
  56.     public void onSectionAttached(int number) {  
  57.         switch (number) {  
  58.             case 1:  
  59.                 mTitle = getString(R.string.title_section1);  
  60.                 break;  
  61.             case 2:  
  62.                 mTitle = getString(R.string.title_section2);  
  63.                 break;  
  64.             case 3:  
  65.                 mTitle = getString(R.string.title_section3);  
  66.                 break;  
  67.         }  
  68.     }  
  69.   
  70.     public void restoreActionBar() {  
  71.         ActionBar actionBar = getSupportActionBar();  
  72.         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);  
  73.         actionBar.setDisplayShowTitleEnabled(true);  
  74.         actionBar.setTitle(mTitle);  
  75.     }  
  76.   
  77.   
  78.     @Override  
  79.     public boolean onCreateOptionsMenu(Menu menu) {  
  80.         if (!mNavigationDrawerFragment.isDrawerOpen()) {  
  81.             // Only show items in the action bar relevant to this screen  
  82.             // if the drawer is not showing. Otherwise, let the drawer  
  83.             // decide what to show in the action bar.  
  84.             getMenuInflater().inflate(R.menu.main, menu);  
  85.             restoreActionBar();  
  86.             return true;  
  87.         }  
  88.         return super.onCreateOptionsMenu(menu);  
  89.     }  
  90.   
  91.     @Override  
  92.     public boolean onOptionsItemSelected(MenuItem item) {  
  93.         // Handle action bar item clicks here. The action bar will  
  94.         // automatically handle clicks on the Home/Up button, so long  
  95.         // as you specify a parent activity in AndroidManifest.xml.  
  96.         int id = item.getItemId();  
  97.         if (id == R.id.action_settings) {  
  98.             return true;  
  99.         }  
  100.         return super.onOptionsItemSelected(item);  
  101.     }  
  102.   
  103.     /** 
  104.      * A placeholder fragment containing a simple view. 
  105.      */  
  106.     public static class PlaceholderFragment extends Fragment {  
  107.         /** 
  108.          * The fragment argument representing the section number for this 
  109.          * fragment. 
  110.          */  
  111.         private static final String ARG_SECTION_NUMBER = "section_number";  
  112.   
  113.         /** 
  114.          * Returns a new instance of this fragment for the given section 
  115.          * number. 
  116.          */  
  117.         public static PlaceholderFragment newInstance(int sectionNumber) {  
  118.             PlaceholderFragment fragment = new PlaceholderFragment();  
  119.             Bundle args = new Bundle();  
  120.             args.putInt(ARG_SECTION_NUMBER, sectionNumber);  
  121.             fragment.setArguments(args);  
  122.             return fragment;  
  123.         }  
  124.   
  125.         public PlaceholderFragment() {  
  126.         }  
  127.   
  128.         @Override  
  129.         public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  130.                 Bundle savedInstanceState) {  
  131.             View rootView = inflater.inflate(R.layout.fragment_main, container, false);  
  132.             TextView textView = (TextView) rootView.findViewById(R.id.section_label);  
  133.             textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));  
  134.             return rootView;  
  135.         }  
  136.   
  137.         @Override  
  138.         public void onAttach(Activity activity) {  
  139.             super.onAttach(activity);  
  140.             ((MainActivity) activity).onSectionAttached(  
  141.                     getArguments().getInt(ARG_SECTION_NUMBER));  
  142.         }  
  143.     }  
  144.   
  145. }  
NavigationDrawerFragment.java  --左边导航抽屉的布局

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.androidsampe1;  
  2.   
  3. import android.support.v7.app.ActionBarActivity;  
  4. import android.app.Activity;  
  5. import android.support.v7.app.ActionBar;  
  6. import android.support.v4.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;  
  24.   
  25. /** 
  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. 
  29.  */  
  30. public class NavigationDrawerFragment extends Fragment {  
  31.   
  32.     /** 
  33.      * Remember the position of the selected item. 
  34.      */  
  35.     private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";  
  36.   
  37.     /** 
  38.      * Per the design guidelines, you should show the drawer on launch until the user manually 
  39.      * expands it. This shared preference tracks this. 
  40.      */  
  41.     private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";  
  42.   
  43.     /** 
  44.      * A pointer to the current callbacks instance (the Activity). 
  45.      */  
  46.     private NavigationDrawerCallbacks mCallbacks;  
  47.   
  48.     /** 
  49.      * Helper component that ties the action bar to the navigation drawer. 
  50.      * 这个导航抽屉监听事件的回调接口,监听打开和关闭 
  51.      */  
  52.     private ActionBarDrawerToggle mDrawerToggle;  
  53.   
  54.     private DrawerLayout mDrawerLayout;  
  55.     private ListView mDrawerListView;  
  56.     private View mFragmentContainerView;  
  57.   
  58.     private int mCurrentSelectedPosition = 0;  
  59.     private boolean mFromSavedInstanceState;  
  60.     private boolean mUserLearnedDrawer;  
  61.   
  62.     public NavigationDrawerFragment() {  
  63.     }  
  64.   
  65.     @Override  
  66.     public void onCreate(Bundle savedInstanceState) {  
  67.         super.onCreate(savedInstanceState);  
  68.   
  69.         // Read in the flag indicating whether or not the user has demonstrated awareness of the  
  70.         // drawer. See PREF_USER_LEARNED_DRAWER for details.  
  71.         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());  
  72.         mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);  
  73.   
  74.         if (savedInstanceState != null) {  
  75.             mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);  
  76.             mFromSavedInstanceState = true;  
  77.         }  
  78.   
  79.         // Select either the default item (0) or the last selected item.  
  80.         selectItem(mCurrentSelectedPosition);  
  81.     }  
  82.   
  83.     @Override  
  84.     public void onActivityCreated (Bundle savedInstanceState) {  
  85.         super.onActivityCreated(savedInstanceState);  
  86.         // Indicate that this fragment would like to influence the set of actions in the action bar.  
  87.         setHasOptionsMenu(true);  
  88.     }  
  89.   
  90.     @Override  
  91.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  92.             Bundle savedInstanceState) {  
  93.         mDrawerListView = (ListView) inflater.inflate(  
  94.                 R.layout.fragment_navigation_drawer, container, false);  
  95.         mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  96.             @Override  
  97.             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
  98.                 selectItem(position);  
  99.             }  
  100.         });  
  101.         mDrawerListView.setAdapter(new ArrayAdapter<String>(  
  102.                 getActionBar().getThemedContext(),  
  103.                 android.R.layout.simple_list_item_1,  
  104.                 android.R.id.text1,  
  105.                 new String[]{  
  106.                         getString(R.string.title_section1),  
  107.                         getString(R.string.title_section2),  
  108.                         getString(R.string.title_section3),  
  109.                 }));  
  110.         mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);  
  111.         return mDrawerListView;  
  112.     }  
  113.   
  114.     public boolean isDrawerOpen() {  
  115.         return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);  
  116.     }  
  117.   
  118.     /** 
  119.      * Users of this fragmentv must call this method to set up the naigation drawer interactions. 
  120.      * 
  121.      * @param fragmentId   The android:id of this fragment in its activity's layout. 
  122.      * @param drawerLayout The DrawerLayout containing this fragment's UI. 
  123.      */  
  124.     public void setUp(int fragmentId, DrawerLayout drawerLayout) {  
  125.         mFragmentContainerView = getActivity().findViewById(fragmentId);  
  126.         mDrawerLayout = drawerLayout;  
  127.   
  128.         // set a custom shadow that overlays the main content when the drawer opens  
  129.         mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);  
  130.         // set up the drawer's list view with items and click listener  
  131.   
  132.         ActionBar actionBar = getActionBar();  
  133.         actionBar.setDisplayHomeAsUpEnabled(true);  
  134.         actionBar.setHomeButtonEnabled(true);  
  135.   
  136.         // ActionBarDrawerToggle ties together the the proper interactions  
  137.         // between the navigation drawer and the action bar app icon.  
  138.         mDrawerToggle = new ActionBarDrawerToggle(  
  139.                 getActivity(),                    /* host Activity */  
  140.                 mDrawerLayout,                    /* DrawerLayout object */  
  141.                 R.drawable.ic_drawer,             /* nav drawer image to replace 'Up' caret */  
  142.                 R.string.navigation_drawer_open,  /* "open drawer" description for accessibility */  
  143.                 R.string.navigation_drawer_close  /* "close drawer" description for accessibility */  
  144.         ) {  
  145.             @Override  
  146.             public void onDrawerClosed(View drawerView) {  
  147.                 super.onDrawerClosed(drawerView);  
  148.                 if (!isAdded()) {  
  149.                     return;  
  150.                 }  
  151.   
  152.                 getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()  
  153.             }  
  154.   
  155.             @Override  
  156.             public void onDrawerOpened(View drawerView) {  
  157.                 super.onDrawerOpened(drawerView);  
  158.                 if (!isAdded()) {  
  159.                     return;  
  160.                 }  
  161.   
  162.                 if (!mUserLearnedDrawer) {  
  163.                         //存储当前的标志位  
  164.                     // The user manually opened the drawer; store this flag to prevent auto-showing  
  165.                     // the navigation drawer automatically in the future.  
  166.                     mUserLearnedDrawer = true;  
  167.                     SharedPreferences sp = PreferenceManager  
  168.                             .getDefaultSharedPreferences(getActivity());  
  169.                     sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).commit();  
  170.                 }  
  171.   
  172.                 getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()  
  173.             }  
  174.         };  
  175.   
  176.         // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,  
  177.         // per the navigation drawer design guidelines.  
  178.         if (!mUserLearnedDrawer && !mFromSavedInstanceState) {  
  179.             mDrawerLayout.openDrawer(mFragmentContainerView);  
  180.         }  
  181.   
  182.         // Defer code dependent on restoration of previous instance state.  
  183.         mDrawerLayout.post(new Runnable() {  
  184.             @Override  
  185.             public void run() {  
  186.                 mDrawerToggle.syncState();  
  187.             }  
  188.         });  
  189.   
  190.         mDrawerLayout.setDrawerListener(mDrawerToggle);  
  191.     }  
  192.   
  193.     private void selectItem(int position) {  
  194.         mCurrentSelectedPosition = position;  
  195.         if (mDrawerListView != null) {  
  196.             mDrawerListView.setItemChecked(position, true);  
  197.         }  
  198.         if (mDrawerLayout != null) {  
  199.             mDrawerLayout.closeDrawer(mFragmentContainerView);  
  200.         }  
  201.         if (mCallbacks != null) {  
  202.             mCallbacks.onNavigationDrawerItemSelected(position);  
  203.         }  
  204.     }  
  205.   
  206.     @Override  
  207.     public void onAttach(Activity activity) {  
  208.         super.onAttach(activity);  
  209.         try {  
  210.             mCallbacks = (NavigationDrawerCallbacks) activity;  
  211.         } catch (ClassCastException e) {  
  212.             throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");  
  213.         }  
  214.     }  
  215.   
  216.     @Override  
  217.     public void onDetach() {  
  218.         super.onDetach();  
  219.         mCallbacks = null;  
  220.     }  
  221.   
  222.     @Override  
  223.     public void onSaveInstanceState(Bundle outState) {  
  224.         super.onSaveInstanceState(outState);  
  225.         outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);  
  226.     }  
  227.   
  228.     @Override  
  229.     public void onConfigurationChanged(Configuration newConfig) {  
  230.         super.onConfigurationChanged(newConfig);  
  231.         // Forward the new configuration the drawer toggle component.  
  232.         mDrawerToggle.onConfigurationChanged(newConfig);  
  233.     }  
  234.   
  235.     @Override  
  236.     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {  
  237.         // If the drawer is open, show the global app actions in the action bar. See also  
  238.         // showGlobalContextActionBar, which controls the top-left area of the action bar.  
  239.         if (mDrawerLayout != null && isDrawerOpen()) {  
  240.             inflater.inflate(R.menu.global, menu);  
  241.             showGlobalContextActionBar();  
  242.         }  
  243.         super.onCreateOptionsMenu(menu, inflater);  
  244.     }  
  245.   
  246.     @Override  
  247.     public boolean onOptionsItemSelected(MenuItem item) {  
  248. <span style="white-space:pre">    </span>//监听Home按钮,Home指的是ActionBar左边的按钮  
  249.         if (mDrawerToggle.onOptionsItemSelected(item)) {  
  250.             return true;  
  251.         }  
  252.   
  253.         if (item.getItemId() == R.id.action_example) {  
  254.             Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();  
  255.             return true;  
  256.         }  
  257.   
  258.         return super.onOptionsItemSelected(item);  
  259.     }  
  260.   
  261.     /** 
  262.      * Per the navigation drawer design guidelines, updates the action bar to show the global app 
  263.      * 'context', rather than just what's in the current screen. 
  264.      */  
  265.     private void showGlobalContextActionBar() {  
  266.         ActionBar actionBar = getActionBar();  
  267.         actionBar.setDisplayShowTitleEnabled(true);  
  268.         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);  
  269.         actionBar.setTitle(R.string.app_name);  
  270.     }  
  271.   
  272.     private ActionBar getActionBar() {  
  273.         return ((ActionBarActivity) getActivity()).getSupportActionBar();  
  274.     }  
  275.   
  276.     /** 
  277.      * Callbacks interface that all activities using this fragment must implement. 
  278.      */  
  279.     public static interface NavigationDrawerCallbacks {  
  280.         /** 
  281.          * Called when an item in the navigation drawer is selected. 
  282.          */  
  283.         void onNavigationDrawerItemSelected(int position);  
  284.     }  
  285. }  

总的来说,框架在V7中已经给出了,我们只需要修改左边导航抽屉的显示内容,已经主界面切换的Fragment就可以了,

这样减少了开发的难度,提高开发效率。

0 0
原创粉丝点击