二、抽屉式菜单栏 DrawerLayout
1、效果图:

2、相关知识点:DrawerLayout, ActionBar, ActionBarDrawerToggle
3、MainActivity 布局文件 activity_main.xml
注意:显示界面主要内容的View(下面为LinearLayout)必须为DrawerLayout的第一个子View,因为XML布局文件中View顺序决定了z-index顺序,这样抽屉菜单将出现在内容之上;
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Content"/>
</LinearLayout>
<!-- The navigation drawer -->
<fragment
android:id="@+id/navigation_drawer_fragment"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="com.yizhui.oschina.ui.NavigationDrawerFragment"
tools:layout="@layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
4、抽屉式菜单内容由NavigationDrawerFragment提供,相关布局文件如下:
fragment_navigation_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/layout_item_bg">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<include layout="@layout/fragment_navigation_drawer_items"></include>
</LinearLayout>
<include layout="@layout/fragment_navigation_drawer_foot"></include>
</LinearLayout>
fragment_navigation_drawer_items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/drawer_menu_item_answer"
style="@style/MenuItemLayoutStyle">
<ImageView
style="@style/MenuItemImageViewStyle"
android:id="@+id/drawer_menu_iv_answer"
android:src="@drawable/drawer_menu_icon_quest_nor" />
<TextView
style="@style/MenuItemTextViewStyle"
android:text="技术问答" />
</LinearLayout>
<View style="@style/h_line"></View>
<LinearLayout
android:id="@+id/drawer_menu_item_opensoft"
style="@style/MenuItemLayoutStyle">
<ImageView
style="@style/MenuItemImageViewStyle"
android:id="@+id/drawer_menu_iv_opensoft"
android:src="@drawable/drawer_menu_icon_opensoft_nor" />
<TextView
style="@style/MenuItemTextViewStyle"
android:text="开源软件" />
</LinearLayout>
<View style="@style/h_line"></View>
<LinearLayout
android:id="@+id/drawer_menu_item_blog"
style="@style/MenuItemLayoutStyle">
<ImageView
style="@style/MenuItemImageViewStyle"
android:id="@+id/drawer_menu_iv_blog"
android:src="@drawable/drawer_menu_icon_blog_nor" />
<TextView
style="@style/MenuItemTextViewStyle"
android:text="博客园" />
</LinearLayout>
<View style="@style/h_line"></View>
<LinearLayout
android:id="@+id/drawer_menu_item_gitclient"
style="@style/MenuItemLayoutStyle">
<ImageView
style="@style/MenuItemImageViewStyle"
android:id="@+id/drawer_menu_iv_gitclient"
android:src="@drawable/drawer_menu_icon_gitapp_nor" />
<TextView
style="@style/MenuItemTextViewStyle"
android:id="@+id/tv_drawer_menu_item"
android:text="Git客户端" />
</LinearLayout>
<View style="@style/h_line"></View>
</LinearLayout>
fragment_navigation_drawer_foot.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false"
android:layout_gravity="bottom"
android:layout_marginBottom="5dp">
<LinearLayout
android:id="@+id/drawer_menu_item_setting"
style="@style/MenuItemLayoutStyle"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center">
<ImageView
style="@style/MenuItemImageViewStyle"
android:src="@drawable/drawer_menu_icon_setting_nor" />
<TextView
style="@style/MenuItemTextViewStyle"
android:text="设置"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/drawer_menu_item_theme"
style="@style/MenuItemLayoutStyle"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center">
<ImageView
style="@style/MenuItemImageViewStyle"
android:src="@drawable/drawer_menu_icon_night_nor" />
<TextView
style="@style/MenuItemTextViewStyle"
android:text="夜间"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
style.xml 抽屉式菜单相关样式:
<!-- 抽屉菜单相关样式 -->
<style name="MenuItemLayoutStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center_vertical</item>
<item name="android:minHeight">55dp</item>
<item name="android:orientation">horizontal</item>
<item name="android:paddingLeft">15dp</item>
<item name="android:background">?attr/layout_item_bg</item>
</style>
<style name="MenuItemImageViewStyle">
<item name="android:layout_height">24dp</item>
<item name="android:layout_width">24dp</item>
</style>
<style name="MenuItemTextViewStyle">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_marginLeft">15dp</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/drawer_menu_text</item>
</style>
<!-- 横向线条 -->
<style name="h_line">
<item name="android:layout_height">1dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:background">?attr/lineColor</item>
</style>
5、NavigationDrawerFragment.java
重点关注 DrawerLayout 与 ActionBarDrawerToggle 的关联
1)ActionBarDrawerToggle 将替代ActionBar的 home/up 图标,需要以下两行代码:
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
2)ActionBarDrawerToggle 是 DrawerLayout.DrawerListener 实现类,
drawerLayout.setDrawerListener(mDrawerToggle) -》 抽屉菜单关联 ActionBarDrawerToggle 动画
public boolean onOptionsItemSelected(MenuItem item) -》 ActionBarDrawerToggle 点击动作关联 DrawerLayout显示或隐藏
mDrawerToggle.syncState(); // Sync the toggle state
设计指南建议,当抽屉菜单显示的时候应该根据情况隐藏ActionBar上的功能菜单并且修改ActionBar标题,可以通过ActionBarDrawerToggle 相关函数实现
package com.yizhui.oschina.ui;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.yizhui.oschina.AppContext;
import com.yizhui.oschina.R;
import butterknife.ButterKnife;
import butterknife.InjectView;
/**
* Created by Yizhui on 2016/5/19.
*/
public class NavigationDrawerFragment extends Fragment implements View.OnClickListener {
@InjectView(R.id.drawer_menu_item_answer)
View mMenuItemAnswer;
@InjectView(R.id.drawer_menu_item_opensoft)
View mMenuItemOpensoft;
@InjectView(R.id.drawer_menu_item_blog)
View mMenuItemBlog;
@InjectView(R.id.drawer_menu_item_gitclient)
View mMenuItemGitclient;
@InjectView(R.id.drawer_menu_item_setting)
View mMenuItemSetting;
@InjectView(R.id.drawer_menu_item_theme)
View mMenuItemTheme;
private ActionBarDrawerToggle mDrawerToggle;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_navigation_drawer,container,false);
ButterKnife.inject(this, view);
initView(view);
return view;
}
private void initView(View view){
mMenuItemAnswer.setOnClickListener(this);
mMenuItemBlog.setOnClickListener(this);
mMenuItemOpensoft.setOnClickListener(this);
mMenuItemGitclient.setOnClickListener(this);
mMenuItemSetting.setOnClickListener(this);
mMenuItemTheme.setOnClickListener(this);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.drawer_menu_item_blog:
break;
case R.id.drawer_menu_item_theme:
AppContext.setNightModeSwitch(!AppContext.getNightModeSwitch());
getActivity().recreate();
break;
}
}
private ActionBar getActionBar(){
return ((AppCompatActivity)getActivity()).getSupportActionBar();
}
public void setupDrawerLayout(DrawerLayout drawerLayout){
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
getActivity(), /* host Activity */
drawerLayout, /* DrawerLayout object */
null, /* 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 */
) {
public void onDrawerClosed(View view) {
//getActionBar().setTitle(mTitle);
//invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
//getActionBar().setTitle(mDrawerTitle);
//invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.syncState(); // Sync the toggle state
drawerLayout.setDrawerListener(mDrawerToggle);
}
@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(mDrawerToggle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
参考文章:
1、泡在网上的日子-android官方侧滑菜单DrawerLayout详解 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0925/1713.html
2、Android官方终于支持 Navigation Drawer(导航抽屉)模式 http://blog.chengyunfeng.com/?p=493
浙公网安备 33010602011771号