文档章节

开源中国客户端侧滑菜单效果实现

爱看博客
 爱看博客
发布于 2015/10/22 10:06
字数 1891
阅读 77
收藏 0

欢迎关注左上角Android技术分享公众号(小红人)。

这篇文章将记录一些关于DrawerLayout的基本用法,我想关于DrawerLayout的用法也许有不少不够了解,这也是比较正常的事情,因为DrawerLayout作为Android组件是Google后来在android中添加的,在android.support.v4包下。


这里用开源中国手机客户端的截图来说明一下,这个DrawerLayout抽屉式布局是什么样子的。

      好,大家已经看到了,当我们手指在屏幕左侧向右滑动时候,就会有一个抽屉式的菜单从左边弹出,并且是“悬浮”在主界面之上的,合理的利用了设备上有限的空间,同样手指在屏幕右侧向左滑动也会出现一个向左弹出的抽屉式菜单,用户体验效果还是不错的,在DrawerLayout出现之前,我们需要做侧滑菜单时,不得不自己实现一个或者使用Github上的开源的项目SlidingMenu,也许是Google也看到了SlidingMenu的强大之处,于是在Android的后期版本中添加了DrawerLayout来实现SlidingMenu同样功能的组件,而且为了兼容早期版本,将其添加在android,support.v4包下。


效果预览


创建抽屉布局

下面这个抽屉布局引用的是android.support.v4.DrawerLayout,类似于LineaLayout、RelativeLayout等布局一样定义,在DrawerLayout内部再定义3个布局,分别是管理主界面的FrameLayout,此布局用来展示界面切换的Fragment,下面是ListView,用来展示菜单列表,最后是一个RelativeLayout,用来展示右边的布局,布局代码如下:

<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" >  
 
   <FrameLayout  
       android:id="@+id/content_frame"  
       android:layout_width="match_parent"  
       android:layout_height="match_parent" />  
 
   <ListView  
       android:id="@+id/left_drawer"  
       android:layout_width="200dp"  
       android:layout_height="match_parent"  
       android:layout_gravity="start"  
       android:background="#111"  
       android:choiceMode="singleChoice"  
       android:divider="@android:color/transparent"  
       android:dividerHeight="0dp" />  
 
   <RelativeLayout  
       android:id="@+id/right_drawer"  
       android:layout_width="220dp"  
       android:layout_height="match_parent"  
       android:layout_gravity="end"  
       android:background="#111"  
       android:gravity="center_horizontal" >  
 
       <TextView  
           android:layout_width="wrap_content"  
           android:layout_height="wrap_content"  
           android:text="这是右边栏"  
           android:textColor="@android:color/white"  
           android:textSize="24sp" />  
   </RelativeLayout>  
 
</android.support.v4.widget.DrawerLayout>

这个布局文件示范了一些重要的布局特征.

  • 主要内容的视图(FrameLayout)必须是DrawLayout的第一个子元素, 因为导航抽屉是在主要内容视图的上面.

  • 主要内容视图设置为匹配父视图的宽度和高度, 因为它代表了整个界面导航抽屉是隐藏的.

  • 抽屉视图(ListView)必须指定其水平重力与android:layout_gravity属性。支持从右到左(RTL)语言,指定值与 "start" 代替 "left"(所以抽屉里出现在布局的右侧当布局是RTL时).这里将ListView设置为左边栏菜单,所以android:layout_gravity属性设置为“start”,将RelativeLayout设置为右边栏,设置android:layout_gravity属性为“end”.

  • 抽屉视图指定其宽度用dp单位和高度匹配父视图。抽屉里的宽度不能超过320 dp, 所以用户总是可以看到主要内容视图的一部分。


初始化抽屉列表

 正如上述所讲,因为DrawerLayout里包含一个ListView作为左边栏侧滑菜单,所以我们需要首先初始化这个抽屉列表,并且为这个列表适配上数据,数据适配器使用的是最简单的ArrayAdapter,模拟数据被简单的定义在res/values/strings.xml里,如下:

<string-array name="menu_array">  
      <item>Menu 1</item>  
      <item>Menu 2</item>  
      <item>Menu 3</item>  
      <item>Menu 4</item>  
</string-array>

      在Java代码中,首先创建一个MainActivity继承了android.support.v4.app.FragmentActivity,因为后续中需要进行Fragment之间的切换。

protected void onCreate(Bundle savedInstanceState) {  
   super.onCreate(savedInstanceState);  
   setContentView(R.layout.activity_main);  
       ......  
   // 初始化菜单列表  
   mMenuTitles = getResources().getStringArray(R.array.menu_array);  
   mMenuListView.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mMenuTitles));  
   mMenuListView.setOnItemClickListener(new DrawerItemClickListener());  
       ......  
}

处理导航点击事件

当用户选择了抽屉列表里面的一个Item时, 系统调用onItemClickListener上的onItemClick(), 给setOnItemClickListener()你在onItemClick()方法里面做什么,在下面的例子中, 选择每一个Item都会在主要内容的布局中插入一个不同的Fragment.并且将导航列表的内容传递给Fragment中显示出来,下面是部分代码:

/**
* ListView上的Item点击事件
*
*/  
private class DrawerItemClickListener implements ListView.OnItemClickListener {  
   @Override  
   public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
       selectItem(position);  
   }  
}  
 
/**
* 切换主视图区域的Fragment
*
* @param position
*/  
private void selectItem(int position) {  
   // TODO Auto-generated method stub  
   Fragment fragment = new ContentFragment();  
   Bundle args = new Bundle();  
   switch (position) {  
   case 0:  
       args.putString("key", mMenuTitles[position]);  
       break;  
   case 1:  
       args.putString("key", mMenuTitles[position]);  
       break;  
   case 2:  
       args.putString("key", mMenuTitles[position]);  
       break;  
   case 3:  
       args.putString("key", mMenuTitles[position]);  
       break;  
   default:  
       break;  
   }  
   fragment.setArguments(args); // FragmentActivity将点击的菜单列表标题传递给Fragment  
   FragmentManager fragmentManager = getSupportFragmentManager();  
   fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();  
 
   // 更新选择后的item和title,然后关闭菜单  
   mMenuListView.setItemChecked(position, true);  
   setTitle(mMenuTitles[position]);  
   mDrawerLayout.closeDrawer(mMenuListView);  
}

开源material-menu的集成

 细心的朋友也许会发现“开源中国客户端主页左上角上有个菜单“动态”的菜单按钮,显示流程是这样的,当菜单没有打开时,显示“三”这样的三条横线,当菜单打开(无论左右菜单)时,会显示“<-”这样的按钮,不停的变化,这样的效果是不是有点绚丽啊?!了解过Android5.0的朋友,应该会知道这种效果是使用了Android5.0新推出的Material Design设计语言做出来的效果,那么该怎么模仿这个效果呢?其实在万能的Github中已经有了这样的效果——material-menu组件。这里就不多说了。

标题栏导航点击事件处理

/**
* 点击ActionBar上菜单
*/  
@Override  
public boolean onOptionsItemSelected(MenuItem item) {  
   int id = item.getItemId();  
   switch (id) {  
   case android.R.id.home:  
       if (showView == mMenuListView) {  
           if (!isDirection_left) { // 左边栏菜单关闭时,打开  
               mDrawerLayout.openDrawer(mMenuListView);  
           } else {// 左边栏菜单打开时,关闭  
               mDrawerLayout.closeDrawer(mMenuListView);  
           }  
       } else if (showView == right_drawer) {  
           if (!isDirection_right) {// 右边栏关闭时,打开  
               mDrawerLayout.openDrawer(right_drawer);  
           } else {// 右边栏打开时,关闭  
               mDrawerLayout.closeDrawer(right_drawer);  
           }  
       }  
       break;  
   case R.id.action_personal:  
       if (!isDirection_right) {// 右边栏关闭时,打开  
           if (showView == mMenuListView) {  
               mDrawerLayout.closeDrawer(mMenuListView);  
           }  
           mDrawerLayout.openDrawer(right_drawer);  
       } else {// 右边栏打开时,关闭  
           mDrawerLayout.closeDrawer(right_drawer);  
       }  
       break;  
   default:  
       break;  
   }  
   return super.onOptionsItemSelected(item);  
}


     这段的逻辑有点绕,事实上我做的是这样的,需要保证主界面上只能最多显示一个菜单布局,当左边的菜单布局展示时,此时打开右边菜单布局时,需要隐藏左边菜单布局;同样,如果右边的菜单布局已经在展示的时候,这时需要打开左边菜单布局,必须首先隐藏掉右边的菜单布局。为了判断当前即将显示或者关闭的是哪个布局,我在全局变量中定义了showView用来标记当前即将显示或者关闭的视图,如果showView==mMenuListView,说明左边菜单布局是即将被显示或隐藏的,这时进一步判断菜单是视图mMenuListView的是否已经显示的标记isDirection_left,来打开或者关闭左边视图菜单。
     同样的道理,如果当前即将显示或者隐藏的是右边导航菜单的话,我们需要进一步判断右边导航是否已经显示,从而进行相关打开或隐藏的决定。

这里的逻辑似乎解释的有点乱,而且代码是分片段贴出来的,不利于理解,需要进一步理解的话,请加QQ群201055521群共享中查看,我已经贴出了所有的Java代码,注释也很详尽,可以方便理解,实在不懂,还可以回复本公众号或加我的个人微信766136833询问。


版权声明:本文原创,转载请注明来自 http://kymjs.com/

本文转载自:http://blog.csdn.net/kymjs/article/details/43817313

共有 人打赏支持
爱看博客
粉丝 5
博文 103
码字总数 23887
作品 0
深圳

暂无文章

简单谈一谈压力测试

最近,在做API的压力测试,趟了不少坑,然后呢,简要记录一下。 压测前需要准备的一些事 拿到API文档不要立马上手,先基准测试,就是执行一次接口测试,至少要压这个接口,要先熟悉一下他的参...

浮躁的码农
35分钟前
0
0
PHP 错误调查

一.定义:PHP错误是由PHP无法读懂执行的代码引起的错误。 二:错误日志 error log 1.在php.ini 里设置 log_errors = on, log文件位置 error_log=/tmp/php_errors.log 2.代码里设置ini_set('...

忙碌的小蜜蜂
38分钟前
0
0
knn算法

import numpy as np def CreateDateSet(): group = np.array([[1.0, 2.0], [1.2, 0.1], [0.1, 1.4], [0.3, 3.5]]) labels = ['A','A','B','B'] return group,labels coding:utf-8 from numpy......

南桥北木
39分钟前
0
0
自己手写一个 SpringMVC 框架

前端框架很多,但没有一个框架称霸,后端框架现在Spring已经完成大一统.所以学习Spring是Java程序员的必修课. Spring 框架对于 Java 后端程序员来说再熟悉不过了,以前只知道它用的反射实现的,...

别打我会飞
今天
2
0
01-《Apache Tomcat 9》之文件索引

《Apache Tomcat 9》是《看Apache官方文档学英语》的第一个专栏!让我们一起在看文档的过程中学英语,在学英语的过程中夯实技术! Documentation Index - 文件索引 Introduction - 介绍 This...

飞鱼说编程
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部