二、抽屉式菜单栏 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

 

posted @ 2016-05-21 19:28  chenyizh  阅读(616)  评论(0)    收藏  举报