ActionBar Fragment运用最佳实践

转载请注明出处:http://blog.csdn.net/sweetvvck/article/details/38645297

通过前面的几篇博客,大家看到了Google是如何解释action bar和fragment以及推荐的用法。俗话说没有demo的博客不是好博客,下面我会介绍一下action bar和fragment在实战中的应用,以及相关demo源码,希望和大家相互交流。

了解过fragment的同学们应该都知道,fragment是android 3.0版本才出现的的,因此如果要在支持android 3.0一下版本的工程中使用fragment的话是需要添加Support Library的。具体如何添加我就不再赘述,可以看我前面的博客Android学习路线(二十一)运用Fragment构建动态UI——创建一个Fragment,下面的项目支持到API Level最低为8,所以项目中也会使用到Support Library。

作为一个有上进心的Android开发者,我们是希望项目的设计符合Android Design的。Android Design是Google官方推荐的应用设计原则,不了解Android Design的同学可以去了解下,我这里有官方翻译文档

我发现“知乎”的App设计是符合Android Design的,那么我们的项目就来模仿知乎的主界面。首先看下效果图:

       

我们来分析一下这样的界面应该怎么实现,从上图可以看出“知乎”android端使用了action bar和drawerlayout,同时drawer中item切换主界面应该是fragment。

新建一个工程FakeZhihu:

  

      从上图可以看到,使用最新的adt插件创建android项目时,如果选择的Minimum Required SDK为8,而Target SDK大于它的话,系统会自动在项目中导入Support v4包;在创建项目向导最后一步可以选择Navigation Type,如果选择了Navigation Drawer,adt工具会在创建项目时自动生成DrawerLayout相关示例代码。但由于DrawerLayout是在高版本的API中出现的,因此adt工具会帮助导入Support v7 appcompat包,这样DrawerLayout就可以兼容到Android2.2了。没有使用最新版的adt工具也没有关系,我提供的demo里有Support v4包和Support v7包,大家可以直接使用。


      下面来看看代码如何实现,android默认的holo主题只提供两种色调,和官方的action bar比较可以看出“知乎”的action bar的颜色以及action bar上action item的颜色以及title的字体大小都是自定义的,那么我们来模仿它自定义一下action bar。


      首先我们打开res目录下的style文件,自定义一个主题和action bar的style,然后在自定义主题中引用自定义的action bar的style:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <!-- the theme applied to the application or activity -->  
  4.     <style name="CustomActionBarTheme"  
  5.            parent="@style/Theme.AppCompat.Light.DarkActionBar">  
  6.         <item name="android:actionBarStyle">@style/MyActionBar</item>  
  7.   
  8.         <!-- Support library compatibility -->  
  9.         <item name="actionBarStyle">@style/MyActionBar</item>  
  10.     </style>  
  11.   
  12.     <!-- ActionBar styles -->  
  13.     <style name="MyActionBar"  
  14.            parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">  
  15.         <item name="android:background">@drawable/actionbar_background</item>  
  16.         <item name="android:titleTextStyle">@style/MyTitleStyle</item>  
  17.   
  18.         <!-- Support library compatibility -->  
  19.         <item name="background">@drawable/actionbar_background</item>  
  20.         <item name="titleTextStyle">@style/MyTitleStyle</item>  
  21.     </style>  
  22.     <style name="MyTitleStyle"  
  23.            parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse">  
  24.         <item name="android:textSize">20dp</item>  
  25.     </style>  
  26. </resources>  
这里要注意的是 无论是在自定义主题还是自定义style时,要根据情况加上parent属性,如果没有加上相应的parent属性的话就不能使用父style中没有被覆盖的样式 。具体如何设置action bar的style可以参考  Android学习路线(九)为Action Bar添加Style

完成自定义主题和style后要记得在manifest文件中应用:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.sweetvvck.fakezhihu"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="8"  
  9.         android:targetSdkVersion="19" />  
  10.   
  11.     <application  
  12.         android:allowBackup="true"  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/CustomActionBarTheme" >  
  16.         <activity  
  17.             android:name="com.sweetvvck.fakezhihu.MainActivity"  
  18.             android:label="@string/app_name" >  
  19.             <intent-filter>  
  20.                 <action android:name="android.intent.action.MAIN" />  
  21.   
  22.                 <category android:name="android.intent.category.LAUNCHER" />  
  23.             </intent-filter>  
  24.         </activity>  
  25.     </application>  
  26.   
  27. </manifest>  
这里可以让整个应用都使用自定义的主题,也可以指定单个activity使用,使用android:theme属性来指定。

接下来要给app添加DrawerLayout了,修改MainActivity的布局文件,添加一个DrawerLayout,内容非常简单,其中包含一个Drawer和内容布局的Container:

[html]  view plain copy 在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.sweetvvck.fakezhihu.MainActivity" >  
  7.   
  8.     <FrameLayout  
  9.         android:id="@+id/container"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent" />  
  12.   
  13.     <fragment  
  14.         android:id="@+id/navigation_drawer"  
  15.         android:name="com.sweetvvck.fakezhihu.NavigationDrawerFragment"  
  16.         android:layout_width="@dimen/navigation_drawer_width"  
  17.         android:layout_height="match_parent"  
  18.         android:layout_gravity="start" />  
  19.   
  20. </android.support.v4.widget.DrawerLayout>  
注意,下面那个fragment就是app的Drawer, 其中的属性android:layout_gravity在这里表示Drawer从哪一侧划出,start代表左侧,end代表右侧;还可以定义两个fragment,然后一个左侧划出一个右侧划出 ,DrawerLayout在之后会详细讲解,这里先简单了解如何使用。

创建完DrawerLayout布局后,我们来为Drawer定义一个fragment,我们可以看到知乎的Drawer中只是包含了一个ListView。这个ListView的第一项和其它项的布局不一样,我们可以想到用ListView加上headerView来实现,知道这些后,我们来创建一个NavigationDrawerFragment继承自Fragment,这个fragment的布局包含一个ListView:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <ListView xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#fff"  
  6.     android:choiceMode="singleChoice"  
  7.     android:divider="#c3c3c3"  
  8.     android:dividerHeight="0.5dp"  
  9.     tools:context="com.sweetvvck.fakezhihu.NavigationDrawerFragment" />  
使用一个ArrayList来存放ListView的数据,定义一个DrawerListItem对象来存放每个Item的title和icon的资源ID:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <string-array name="item_title">  
  2.     <item>首页</item>  
  3.     <item>发现</item>  
  4.     <item>关注</item>  
  5.     <item>收藏</item>  
  6.     <item>草稿</item>  
  7.     <item>搜索</item>  
  8.     <item>提问</item>  
  9.     <item>设置</item>  
  10. </string-array>  
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. String[] itemTitle = getResources().getStringArray(R.array.item_title);  
  2. int[] itemIconRes = {  
  3.   R.drawable.ic_drawer_home,  
  4.   R.drawable.ic_drawer_explore,  
  5.   R.drawable.ic_drawer_follow,  
  6.   R.drawable.ic_drawer_collect,  
  7.   R.drawable.ic_drawer_draft,  
  8.   R.drawable.ic_drawer_search,  
  9.   R.drawable.ic_drawer_question,  
  10.   R.drawable.ic_drawer_setting};  
  11.          
  12. for (int i = 0; i < itemTitle.length; i++) {  
  13.     DrawerListItem item = new DrawerListItem(getResources().getDrawable(itemIconRes[i]), itemTitle[i]);  
  14.     mData.add(item);  
  15.   
  16. }  
准备好数据后为该ListView设置Adapter,我们发现这个ListView是Single Choice模式的,并且每个Item被选中后会高亮。那么如何来实现这个功能呢?

实现这样的效果有两个步骤:

      第一:在ListView中指定android:choiceMode="singleChoice";

      第二:给ListView的Item的布局设置一个特殊的背景drawable,这个drawable包含当状态为activated时的背景和常态下的背景;同时这个item布局中的图片src和文字颜色也要坐相应的设置;

item的背景:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item android:state_activated="true" android:drawable="@drawable/activated_background_color" />  
  4.     <item android:drawable="@android:color/transparent" />  
  5. </selector>  
图片的src,这里以home为例:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item android:state_activated="true" android:drawable="@drawable/ic_drawer_home_pressed" />  
  4.     <item android:drawable="@drawable/ic_drawer_home_normal" />  
  5. </selector>  
文字的颜色:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- Copyright (C) 2011 Google Inc. All Rights Reserved. -->  
  3. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  4.     <item android:state_enabled="false"  
  5.         android:color="#ff999999"/>  
  6.     <item android:state_activated="true"  
  7.         android:color="@android:color/white" />  
  8.     <item  
  9.         android:color="#636363" />  
  10. </selector>  
这样就能实现ListView点击Item高亮的效果了。


考虑到用户在第一次使用app的时候可能不知道有Drawer的存在,我们可以在app第一次被启动时让Drawer处于打开状态,之后再默认隐藏,这是实际项目中常用的手段,这里我们用sharedpreference来实现:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 通过这个flag判断用户是否已经知道drawer了,第一次启动应用显示出drawer(抽屉),之后启动应用默认将其  
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());  
  2. mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);  
接下来,要实现Drawer的fragment和宿主activity之间的通讯,需要定义一个回调接口,并且在宿主activity中实现:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**  
  2. * 宿主activity要实现的回调接口  
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. * 用于activity与该fragment之间通讯  
  2. */  
  3. public static interface NavigationDrawerCallbacks {  
  4.     /** 
  5.      * 当drawer中的某个item被选择是调用该方法 
  6.     */  
  7.     void onNavigationDrawerItemSelected(String title);  
  8. }  
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public void onNavigationDrawerItemSelected(String title) {  
  3.     FragmentManager fragmentManager = getSupportFragmentManager();  
  4.     FragmentTransaction ft = fragmentManager.beginTransaction();  
  5.     currentFragment = fragmentManager.findFragmentByTag(title);  
  6.     if(currentFragment == null) {  
  7.         currentFragment = ContentFragment.newInstance(title);  
  8.         ft.add(R.id.container, currentFragment, title);  
  9.     }  
  10.     if(lastFragment != null) {  
  11.         ft.hide(lastFragment);  
  12.     }  
  13.     if(currentFragment.isDetached()){  
  14.         ft.attach(currentFragment);  
  15.     }  
  16.     ft.show(currentFragment);  
  17.     lastFragment = currentFragment;  
  18.     ft.commit();  
  19.     onSectionAttached(title);  
  20. }  
具体如何来创建一个fragment以及如何实现fragment和activity之间的通讯,可以参考: Android学习路线(二十一)运用Fragment构建动态UI——创建一个Fragment  和  Android学习路线(二十三)运用Fragment构建动态UI——Fragment间通讯  ;完整的 NavigationDrawerFragment代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.sweetvvck.fakezhihu;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.SharedPreferences;  
  8. import android.content.res.Configuration;  
  9. import android.os.Bundle;  
  10. import android.preference.PreferenceManager;  
  11. import android.support.v4.app.ActionBarDrawerToggle;  
  12. import android.support.v4.app.Fragment;  
  13. import android.support.v4.view.GravityCompat;  
  14. import android.support.v4.widget.DrawerLayout;  
  15. import android.support.v7.app.ActionBar;  
  16. import android.support.v7.app.ActionBarActivity;  
  17. import android.view.LayoutInflater;  
  18. import android.view.Menu;  
  19. import android.view.MenuInflater;  
  20. import android.view.MenuItem;  
  21. import android.view.View;  
  22. import android.view.ViewGroup;  
  23. import android.widget.AdapterView;  
  24. import android.widget.ListView;  
  25. import android.widget.Toast;  
  26.   
  27. /** 
  28.  * 用于管理交互和展示抽屉导航的Fragment。 
  29.  * 参考<a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction"> 
  30.  * 设计向导</a>  
  31.  */  
  32. public class NavigationDrawerFragment extends Fragment {  
  33.   
  34.     /** 
  35.      * 存放选中item的位置 
  36.      */  
  37.     private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";  
  38.   
  39.     /** 
  40.      * 存放用户是否需要默认开启drawer的key 
  41.      */  
  42.     private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";  
  43.   
  44.     /** 
  45.      * 宿主activity实现的回调接口的引用 
  46.      */  
  47.     private NavigationDrawerCallbacks mCallbacks;  
  48.   
  49.     /** 
  50.      * 将action bar和drawerlayout绑定的组件 
  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.     private List<DrawerListItem> mData = new ArrayList<DrawerListItem>();  
  62.   
  63.     public NavigationDrawerFragment() {  
  64.     }  
  65.   
  66.     @Override  
  67.     public void onCreate(Bundle savedInstanceState) {  
  68.         super.onCreate(savedInstanceState);  
  69.   
  70.         // 通过这个flag判断用户是否已经知道drawer了,第一次启动应用显示出drawer(抽屉),之后启动应用默认将其隐藏  
  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.     }  
  80.   
  81.     @Override  
  82.     public void onActivityCreated (Bundle savedInstanceState) {  
  83.         super.onActivityCreated(savedInstanceState);  
  84.         // 设置该fragment拥有自己的actionbar action item  
  85.         setHasOptionsMenu(true);  
  86.     }  
  87.   
  88.     @Override  
  89.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  90.             Bundle savedInstanceState) {  
  91.         mDrawerListView = (ListView) inflater.inflate(R.layout.fragment_navigation_drawer, container, false);  
  92.         View headerView = inflater.inflate(R.layout.list_header, null);  
  93.         mDrawerListView.addHeaderView(headerView);  
  94.         mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  95.             @Override  
  96.             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
  97.                 selectItem(position);  
  98.             }  
  99.         });  
  100.         String[] itemTitle = getResources().getStringArray(R.array.item_title);  
  101.         int[] itemIconRes = {  
  102.             R.drawable.ic_drawer_home,  
  103.             R.drawable.ic_drawer_explore,  
  104.             R.drawable.ic_drawer_follow,  
  105.             R.drawable.ic_drawer_collect,  
  106.             R.drawable.ic_drawer_draft,  
  107.             R.drawable.ic_drawer_search,  
  108.             R.drawable.ic_drawer_question,  
  109.             R.drawable.ic_drawer_setting};  
  110.           
  111.         for (int i = 0; i < itemTitle.length; i++) {  
  112.             DrawerListItem item = new DrawerListItem(getResources().getDrawable(itemIconRes[i]), itemTitle[i]);  
  113.             mData.add(item);  
  114.               
  115.         }  
  116.         selectItem(mCurrentSelectedPosition);  
  117.         DrawerListAdapter adapter = new DrawerListAdapter(this.getActivity(), mData);  
  118.         mDrawerListView.setAdapter(adapter);  
  119.         mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);  
  120.         return mDrawerListView;  
  121.     }  
  122.   
  123.     public boolean isDrawerOpen() {  
  124.         return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);  
  125.     }  
  126.   
  127.     /** 
  128.      * 设置导航drawer 
  129.      * 
  130.      * @param fragmentId   fragmentent的id 
  131.      * @param drawerLayout fragment的容器 
  132.      */  
  133.     public void setUp(int fragmentId, DrawerLayout drawerLayout) {  
  134.         mFragmentContainerView = getActivity().findViewById(fragmentId);  
  135.         mDrawerLayout = drawerLayout;  
  136.   
  137.         mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);  
  138.   
  139.         ActionBar actionBar = getActionBar();  
  140.         actionBar.setDisplayHomeAsUpEnabled(true);  
  141.         actionBar.setHomeButtonEnabled(true);  
  142.         //隐藏Action bar上的app icon  
  143.         actionBar.setDisplayShowHomeEnabled(false);  
  144.   
  145.         mDrawerToggle = new ActionBarDrawerToggle(  
  146.                 getActivity(),                    /* 宿主 */  
  147.                 mDrawerLayout,                    /* DrawerLayout 对象 */  
  148.                 R.drawable.ic_drawer,             /* 替换actionbar上的'Up'图标 */  
  149.                 R.string.navigation_drawer_open,    
  150.                 R.string.navigation_drawer_close  
  151.         ) {  
  152.             @Override  
  153.             public void onDrawerClosed(View drawerView) {  
  154.                 super.onDrawerClosed(drawerView);  
  155.                 if (!isAdded()) {  
  156.                     return;  
  157.                 }  
  158.   
  159.                 getActivity().supportInvalidateOptionsMenu(); // 调用 onPrepareOptionsMenu()  
  160.             }  
  161.   
  162.             @Override  
  163.             public void onDrawerOpened(View drawerView) {  
  164.                 super.onDrawerOpened(drawerView);  
  165.                 if (!isAdded()) {  
  166.                     return;  
  167.                 }  
  168.   
  169.                 if (!mUserLearnedDrawer) {  
  170.                     mUserLearnedDrawer = true;  
  171.                     SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());  
  172.                     sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).commit();  
  173.                 }  
  174.   
  175.                 getActivity().supportInvalidateOptionsMenu(); // 调用 onPrepareOptionsMenu()  
  176.             }  
  177.         };  
  178.   
  179.         // 如果是第一次进入应用,显示抽屉  
  180.         if (!mUserLearnedDrawer && !mFromSavedInstanceState) {  
  181.             mDrawerLayout.openDrawer(mFragmentContainerView);  
  182.         }  
  183.   
  184.         mDrawerLayout.post(new Runnable() {  
  185.             @Override  
  186.             public void run() {  
  187.                 mDrawerToggle.syncState();  
  188.             }  
  189.         });  
  190.   
  191.         mDrawerLayout.setDrawerListener(mDrawerToggle);  
  192.     }  
  193.   
  194.     private void selectItem(int position) {  
  195.         mCurrentSelectedPosition = position;  
  196.         if (mDrawerListView != null) {  
  197.             mDrawerListView.setItemChecked(position, true);  
  198.         }  
  199.         if (mDrawerLayout != null) {  
  200.             mDrawerLayout.closeDrawer(mFragmentContainerView);  
  201.         }  
  202.         if (mCallbacks != null) {  
  203.             if(mCurrentSelectedPosition == 0) {  
  204.                 mCallbacks.onNavigationDrawerItemSelected(getString(R.string.app_name));  
  205.                 return;  
  206.             }  
  207.             mCallbacks.onNavigationDrawerItemSelected(mData.get(position - 1).getTitle());  
  208.         }  
  209.     }  
  210.   
  211.     @Override  
  212.     public void onAttach(Activity activity) {  
  213.         super.onAttach(activity);  
  214.         try {  
  215.             mCallbacks = (NavigationDrawerCallbacks) activity;  
  216.         } catch (ClassCastException e) {  
  217.             throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");  
  218.         }  
  219.     }  
  220.   
  221.     @Override  
  222.     public void onDetach() {  
  223.         super.onDetach();  
  224.         mCallbacks = null;  
  225.     }  
  226.   
  227.     @Override  
  228.     public void onSaveInstanceState(Bundle outState) {  
  229.         super.onSaveInstanceState(outState);  
  230.         outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);  
  231.     }  
  232.   
  233.     @Override  
  234.     public void onConfigurationChanged(Configuration newConfig) {  
  235.         super.onConfigurationChanged(newConfig);  
  236.         // 当系统配置改变时调用DrawerToggle的改变配置方法(例如横竖屏切换会回调此方法)  
  237.         mDrawerToggle.onConfigurationChanged(newConfig);  
  238.     }  
  239.   
  240.     @Override  
  241.     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {  
  242.         //当抽屉打开时显示应用全局的actionbar设置  
  243.         if (mDrawerLayout != null && isDrawerOpen()) {  
  244.             inflater.inflate(R.menu.global, menu);  
  245.             showGlobalContextActionBar();  
  246.         }  
  247.         super.onCreateOptionsMenu(menu, inflater);  
  248.     }  
  249.   
  250.     @Override  
  251.     public boolean onOptionsItemSelected(MenuItem item) {  
  252.         if (mDrawerToggle.onOptionsItemSelected(item)) {  
  253.             return true;  
  254.         }  
  255.   
  256.         if (item.getItemId() == R.id.action_example) {  
  257.             Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();  
  258.             return true;  
  259.         }  
  260.   
  261.         return super.onOptionsItemSelected(item);  
  262.     }  
  263.   
  264.     /** 
  265.      * 当抽屉打开时显示应用全局的actionbar设置 
  266.      */  
  267.     private void showGlobalContextActionBar() {  
  268.         ActionBar actionBar = getActionBar();  
  269.         actionBar.setDisplayShowTitleEnabled(true);  
  270.         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);  
  271.         actionBar.setTitle(R.string.app_name);  
  272.     }  
  273.   
  274.     private ActionBar getActionBar() {  
  275.         return ((ActionBarActivity) getActivity()).getSupportActionBar();  
  276.     }  
  277.   
  278.     /** 
  279.      * 宿主activity要实现的回调接口 
  280.      * 用于activity与该fragment之间通讯 
  281.      */  
  282.     public static interface NavigationDrawerCallbacks {  
  283.         /** 
  284.          * 当drawer中的某个item被选择是调用该方法 
  285.          */  
  286.         void onNavigationDrawerItemSelected(String title);  
  287.     }  
  288.       
  289. }  


这样就完成模仿“知乎”主界面的demo的开发啦,来看看效果如何:


     

怎么样,很像吧,Drawer是不是简直可以以假乱真了,哈哈。

demo地址:http://download.csdn.net/detail/sweetvvck/7794083

其实demo中还有写知识点没有讲到,比如drawer划开时和关闭时action bar上的action item其实是不一样的,这时如何实现的呢?怎么设置action bar不现实logo/icon?选择Drawer中listview的item切换fragment可以每选择一次都replace一次fragment,但是这样每次都得重新创建一个fragment,如果fragment初始化较复杂就更占资源,此时可以配合使用add,hide,show来实现切换同时将以加载过的fragment缓存起来......由于篇幅原因,这些问题都会在之后的博客中详细讲到的~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值