Android App中DrawerLayout抽屉效果的菜单编写实例


Posted in PHP onMarch 21, 2016

抽屉效果的导航菜单
看了很多应用,觉得这种侧滑的抽屉效果的菜单很好。

Android App中DrawerLayout抽屉效果的菜单编写实例

不用切换到另一个页面,也不用去按菜单的硬件按钮,直接在界面上一个按钮点击,菜单就滑出来,而且感觉能放很多东西。
库的引用:
首先, DrawerLayout这个类是在Support Library里的,需要加上android-support-v4.jar这个包。

然后程序中用时在前面导入import android.support.v4.widget.DrawerLayout;

如果找不到这个类,首先用SDK Manager更新一下Android Support Library,然后在Android SDK\extras\android\support\v4路径下找到android-support-v4.jar,复制到项目的libs路径,将其Add to Build Path.

代码1
布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >

  <android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- The main content view -->
    <!-- main content must be the first element of DrawerLayout because it will be drawn first and drawer must be on top of it -->

    <FrameLayout
      android:id="@+id/content_frame"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

    <!-- The navigation drawer -->

    <ListView
      android:id="@+id/left_drawer"
      android:layout_width="240dp"
      android:layout_height="match_parent"
      android:layout_gravity="left"
      android:background="#111"
      android:choiceMode="singleChoice"
      android:divider="@android:color/transparent"
      android:dividerHeight="0dp" />
  </android.support.v4.widget.DrawerLayout>

</RelativeLayout> 

DrawerLayout的第一个子元素是主要内容,即抽屉没有打开时显示的布局。这里采用了一个FrameLayout,里面什么也没放。

DrawerLayout的第二个子元素是抽屉中的内容,即抽屉布局,这里采用了一个ListView。

主要的Activity(从官方实例中扒出来的):

package com.example.hellodrawer;

import android.os.Bundle;
import android.app.Activity;
import android.content.res.Configuration;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;

public class HelloDrawerActivity extends Activity
{

  private String[] mPlanetTitles;
  private DrawerLayout mDrawerLayout;
  private ActionBarDrawerToggle mDrawerToggle;
  private ListView mDrawerList;

  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_hello_drawer);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    // init the ListView and Adapter, nothing new
    initListView();

    // set a custom shadow that overlays the main content when the drawer
    // opens
    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
        GravityCompat.START);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
        R.drawable.ic_drawer, R.string.drawer_open,
        R.string.drawer_close)
    {

      /** Called when a drawer has settled in a completely closed state. */
      public void onDrawerClosed(View view)
      {

        invalidateOptionsMenu(); // creates call to
                      // onPrepareOptionsMenu()
      }

      /** Called when a drawer has settled in a completely open state. */
      public void onDrawerOpened(View drawerView)
      {

        invalidateOptionsMenu(); // creates call to
                      // onPrepareOptionsMenu()
      }
    };

    // Set the drawer toggle as the DrawerListener
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    // enable ActionBar app icon to behave as action to toggle nav drawer
    getActionBar().setDisplayHomeAsUpEnabled(true);
    // getActionBar().setHomeButtonEnabled(true);
    // Note: getActionBar() Added in API level 11
  }

  private void initListView()
  {
    mDrawerList = (ListView) findViewById(R.id.left_drawer);

    mPlanetTitles = getResources().getStringArray(R.array.planets_array);

    // Set the adapter for the list view
    mDrawerList.setAdapter(new ArrayAdapter<String>(this,
        R.layout.list_item, mPlanetTitles));
    // Set the list's click listener
    mDrawerList.setOnItemClickListener(new OnItemClickListener()
    {

      @Override
      public void onItemClick(AdapterView<?> parent, View view,
          int position, long id)
      {
        // Highlight the selected item, update the title, and close the
        // drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(mPlanetTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
      }
    });
  }

  @Override
  protected void onPostCreate(Bundle savedInstanceState)
  {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
  }

  @Override
  public void onConfigurationChanged(Configuration newConfig)
  {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item)
  {
    // Pass the event to ActionBarDrawerToggle, if it returns
    // true, then it has handled the app icon touch event
    if (mDrawerToggle.onOptionsItemSelected(item))
    {
      return true;
    }
    // Handle your other action bar items...

    return super.onOptionsItemSelected(item);
  }

}

比较纠结的是用了Level 11的一个API,这样minSdkVersion就有限制,不能太低。

图片资源Android官网示例处提供下载了。

程序运行后效果如下:
抽屉打开前:

Android App中DrawerLayout抽屉效果的菜单编写实例

抽屉打开后:

Android App中DrawerLayout抽屉效果的菜单编写实例

代码2
今天又看了一下DrawerLayout的类,发现有很多方法可以直接用的。

重新试了一下,其实不用上面那么麻烦,随便自己定义一个按钮控制抽屉的打开就行:

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".DrawerActivity" >

  <android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- The main content view -->

    <FrameLayout
      android:id="@+id/content_frame"
      android:layout_width="match_parent"
      android:layout_height="match_parent" >

      <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="open" 
        />
    </FrameLayout>

    <!-- The navigation drawer -->

    <ListView
      android:id="@+id/left_drawer"
      android:layout_width="240dp"
      android:layout_height="match_parent"
      android:layout_gravity="start"
      android:background="#111"
      android:choiceMode="singleChoice"
      android:divider="@android:color/transparent"
      android:dividerHeight="0dp" />
  </android.support.v4.widget.DrawerLayout>

</RelativeLayout>

 
主要代码:

package com.example.hellodrawer;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.widget.DrawerLayout;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class DrawerActivity extends Activity
{
  private DrawerLayout mDrawerLayout = null;

  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_drawer);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    Button button = (Button) findViewById(R.id.btn);
    button.setOnClickListener(new OnClickListener()
    {

      @Override
      public void onClick(View v)
      {
        // 按钮按下,将抽屉打开
        mDrawerLayout.openDrawer(Gravity.LEFT);

      }
    });
  }

}

使用Toolbar + DrawerLayout快速实现高大上菜单侧滑
如果你有在关注一些遵循最新的Material Design设计规范的应用的话(如果没有,假设你有!),也许会发现有很多使用了看起来很舒服、很高大上的侧滑菜单动画效果,示例如下(via 参考2):

Android App中DrawerLayout抽屉效果的菜单编写实例

今天就来使用官方支持库来快速实现这类效果,需要使用到Toolbar和DrawerLayout,详细步骤如下:(如果你还不知道这两个Widget,先自己Google吧~)
首先需要添加appcompat-v7支持:

如果是在Android Studio 1.0 RC4上创建的项目,默认已经添加了appcompat-v7支持了,如果不是最新版AS则需要在build.gradle中添加如下代码:

dependencies {
  ...//其他代码
  compile 'com.android.support:appcompat-v7:21.0.2'
}

添加完成后需要同步一下gradle

添加Toolbar:

由于Toolbar是继承自View,所以可以像其他标准控件一样直接主布局文件添加Toolbar,但是为了提高Toolbar的重用效率,可以在layout创建一个custom_toolbar.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
  <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tl_custom"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
</android.support.v7.widget.Toolbar>

说明:

android.support.v7.widget.Toolbar - 当然如果只在Lollipop中可以直接使用Toolbar而不需要加上v7支持
xmlns:app - 自定义xml命名控件,在AS中可以直接指定res-auto而不需要使用完整包名
android:background 和 android:minHeight 均可以在styles.xml中声明
添加DrawerLayout:

和Toolbar类似,为了提高代码重用效率,可以在layout中创建一个custom_drawerlayout.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
  <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dl_left"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <!--主布局-->
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
      android:id="@+id/iv_main"
      android:layout_width="100dp"
      android:layout_height="100dp" />
  </LinearLayout>
  <!--侧滑菜单-->
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:layout_gravity="start">
    <ListView
      android:id="@+id/lv_left_menu"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:divider="@null"
      android:text="DrawerLayout" />
  </LinearLayout>
</android.support.v4.widget.DrawerLayout>

Drawerlayout标签中有两个子节点,一个是左边菜单,一个是主布局,另外需要在左边菜单起始位置设置为android:layout_gravity="start"

实现activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context=".MainActivity">
    <!--Toolbar-->
    <include layout="@layout/custom_toolbar" />
    <!--DrawerLayout-->
    <include layout="@layout/custom_drawerlayout" />
</LinearLayout>

直接使用include标签,简洁明了

完善Java代码:

public class MainActivity extends ActionBarActivity {
  //声明相关变量
  private Toolbar toolbar;
  private DrawerLayout mDrawerLayout;
  private ActionBarDrawerToggle mDrawerToggle;
  private ListView lvLeftMenu;
  private String[] lvs = {"List Item 01", "List Item 02", "List Item 03", "List Item 04"};
  private ArrayAdapter arrayAdapter;
  private ImageView ivRunningMan;
  private AnimationDrawable mAnimationDrawable;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViews(); //获取控件
    //京东RunningMan动画效果,和本次Toolbar无关
    mAnimationDrawable = (AnimationDrawable) ivRunningMan.getBackground();
    mAnimationDrawable.start();
    toolbar.setTitle("Toolbar");//设置Toolbar标题
    toolbar.setTitleTextColor(Color.parseColor("#ffffff")); //设置标题颜色
    setSupportActionBar(toolbar);
    getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    //创建返回键,并实现打开关/闭监听
    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.open, R.string.close) {
      @Override
      public void onDrawerOpened(View drawerView) {
        super.onDrawerOpened(drawerView);
        mAnimationDrawable.stop();
      }
      @Override
      public void onDrawerClosed(View drawerView) {
        super.onDrawerClosed(drawerView);
        mAnimationDrawable.start();
      }
    };
    mDrawerToggle.syncState();
    mDrawerLayout.setDrawerListener(mDrawerToggle);
    //设置菜单列表
    arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, lvs);
    lvLeftMenu.setAdapter(arrayAdapter);
  }
  private void findViews() {
    ivRunningMan = (ImageView) findViewById(R.id.iv_main);
    toolbar = (Toolbar) findViewById(R.id.tl_custom);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.dl_left);
    lvLeftMenu = (ListView) findViewById(R.id.lv_left_menu);
  }
}

当然比较重要还有styles.xml和colors.xml,具体如下: 

<resources>
  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!--状态栏颜色-->
    <item name="colorPrimaryDark">@color/Indigo_colorPrimaryDark</item>
    <!--Toolbar颜色-->
    <item name="colorPrimary">@color/Indigo_colorPrimary</item>
    <!--返回键样式-->
    <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
    </style>
    <style name="AppTheme.DrawerArrowToggle" parent="Base.Widget.AppCompat.DrawerArrowToggle">
    <item name="color">@android:color/white</item>
  </style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <color name="Indigo_colorPrimaryDark">#303f9f</color>
  <color name="Indigo_colorPrimary">#3f51b5</color>
  <color name="Indigo_nav_color">#4675FF</color>
</resources>

到此就实现了高大上菜单侧滑,最终效果如下(注:在Yosemite上貌似直接Record手机屏幕貌似不起作用,而且动画由于帧率原因无法实时,就先这样看吧~)

Android App中DrawerLayout抽屉效果的菜单编写实例

PHP 相关文章推荐
十天学会php之第三天
Oct 09 PHP
php无限分类且支持输出树状图的详细介绍
Jun 19 PHP
浅析PHP页面局部刷新功能的实现小结
Jun 21 PHP
如何阻止网站被恶意反向代理访问(防网站镜像)
Mar 18 PHP
php解析http获取的json字符串变量总是空白null
Mar 02 PHP
PHP中的命名空间详细介绍
Jul 02 PHP
php实现购物车功能(下)
Jan 05 PHP
thinkPHP3.2简单实现文件上传的方法
May 16 PHP
php中mkdir()函数的权限问题分析
Sep 24 PHP
thinkPHP中volist标签用法示例
Dec 06 PHP
PHP更安全的密码加密机制Bcrypt详解
Jun 18 PHP
PHP基于mcript扩展实现对称加密功能示例
Feb 21 PHP
PHP的Laravel框架结合MySQL与Redis数据库的使用部署
Mar 21 #PHP
PHP编写学校网站上新生注册登陆程序的实例分享
Mar 21 #PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
Mar 21 #PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
Mar 21 #PHP
PHP编程中尝试程序并发的几种方式总结
Mar 21 #PHP
PHP的Laravel框架中使用消息队列queue及异步队列的方法
Mar 21 #PHP
Zend Framework框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法
Mar 21 #PHP
You might like
php下使用SimpleXML 处理XML 文件
2010/02/27 PHP
php 模拟GMAIL,HOTMAIL(MSN),YAHOO,163,126邮箱登录的详细介绍
2013/06/18 PHP
php实现中文转数字
2016/02/18 PHP
Yii实现复选框批量操作实例代码
2017/03/15 PHP
你必须知道的Javascript知识点之&quot;this指针&quot;的应用
2013/04/23 Javascript
Jquery 的outerHeight方法使用介绍
2013/09/11 Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
2015/03/03 Javascript
web 屏蔽BackSpace键实例代码
2016/12/24 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
Bootstrap笔记之缩略图、警告框实例详解
2017/03/09 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
2017/04/13 Javascript
前端常见跨域解决方案(全)
2017/09/19 Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
2018/07/17 Javascript
vue中组件的过渡动画及实现代码
2018/11/21 Javascript
vue响应式系统之observe、watcher、dep的源码解析
2019/04/09 Javascript
微信小程序开发之map地图组件定位并手动修改位置偏差
2019/08/17 Javascript
laydate只显示时分 不显示秒的功能实现方法
2019/09/28 Javascript
Element实现表格嵌套、多个表格共用一个表头的方法
2020/05/09 Javascript
微信小程序:报错(in promise) MiniProgramError
2020/10/30 Javascript
Python代码的打包与发布详解
2014/07/30 Python
Python实现全角半角转换的方法
2014/08/18 Python
简单谈谈python的反射机制
2016/06/28 Python
利用Django-environ如何区分不同环境
2018/08/26 Python
解决PyCharm不运行脚本,而是运行单元测试的问题
2019/01/17 Python
利用python脚本如何简化jar操作命令
2019/02/24 Python
django 消息框架 message使用详解
2019/07/22 Python
linux mint中搜狗输入法导致pycharm卡死的问题
2020/10/28 Python
工作态度检讨书
2014/02/11 职场文书
人力资源部经理助理岗位职责
2014/03/04 职场文书
干部选拔任用方案
2014/05/26 职场文书
党员一帮一活动总结
2014/07/08 职场文书
我爱家乡演讲稿
2014/09/12 职场文书
群众路线教育实践活动个人对照检查材料思想汇报(社区班子)
2014/10/06 职场文书
2014年中班下学期工作总结
2014/12/11 职场文书
小学班主任个人总结
2015/03/03 职场文书
运动会宣传稿50字
2015/07/23 职场文书