在android support.v4 中有一个抽屉视图控件DrawerLayout。使用这个控件,可以生成通过在屏幕上水平滑动打开或者关闭菜单,能给用户一个不错的体验效果。

   最近在项目中,设计中有用到这个效果,但是是左右两边都能划出这样的一个菜单效果。经过使用发现,在xml布局中和代码中,几乎是添加添加同样的代码,就可以实现这种作用两种菜单的效果。

   效果图如下:

   左边拉出菜单:

wKioL1PqO2qAdhROAAFVeVvcljs115.jpg

         右边拉出菜单效果:

wKioL1PqO2rxFo0UAAFHz2zoAC0127.jpg

    具体的实现方法如下,结合代码文件,跟大家分享一下:


    1. 主页布局文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<? 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/main_drawer_layout"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent"
     android:background = "@android:color/transparent"  >
 
     < RelativeLayout
         android:id = "@+id/main_content_frame_parent"
         android:layout_width = "match_parent"
         android:layout_height = "match_parent"
         android:background = "@android:color/transparent"  >
     <!-- 下层显示的主要内容 -->
         < FrameLayout
             android:id = "@+id/main_content_frame"
             android:layout_width = "match_parent"
             android:layout_height = "match_parent"
             android:background = "@android:color/white"
             android:scrollbars = "vertical"  >
         </ FrameLayout >
     </ RelativeLayout >
     <!-- 左侧滑动栏 -->
     < RelativeLayout
         android:id = "@+id/main_left_drawer_layout"
         android:layout_width = "240dp"
         android:layout_height = "match_parent"
         android:layout_gravity = "start"
         android:background = "@android:color/transparent"
         android:paddingTop = "50dp"  >
     </ RelativeLayout >
     <!-- 右侧滑动栏 -->
 
     < RelativeLayout
         android:id = "@+id/main_right_drawer_layout"
         android:layout_width = "240dp"
         android:layout_height = "match_parent"
         android:layout_gravity = "end"
         android:background = "@android:color/transparent"
         android:paddingTop = "50dp"  >
     </ RelativeLayout >
 
</ android.support.v4.widget.DrawerLayout >

如上,使用DrawerLayout需要在布局文件跟目录中引用,v4包中的DrawerLayout标签,并且宽和高,都设置为match_parent.里面framelayout用来现实菜单收起时,下层页面的布局。

    而main_left_drawer_layout和main_right_drawer_layout为左右两个抽屉菜单对应的父layout,需要注意的是,在DrawerLayout中,从左侧开始使用android:layout_gravity="start",从右侧开始,使用 android:layout_gravity="end"。  

     

     b.主布局代码文件:

    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package  com.demo.drawlayout;
 
import  android.os.Bundle;
import  android.support.v4.app.ActionBarDrawerToggle;
import  android.support.v4.app.FragmentActivity;
import  android.support.v4.app.FragmentManager;
import  android.support.v4.app.FragmentTransaction;
import  android.support.v4.widget.DrawerLayout;
import  android.view.View;
import  android.widget.RelativeLayout;
import  android.widget.TextView;
 
 
public  class  MainFrameLayout  extends  FragmentActivity {
     // 抽屉菜单对象
     private  ActionBarDrawerToggle drawerbar;
     public  DrawerLayout drawerLayout;
     private  TestFragment testFragment;
     private  RelativeLayout left_menu_layout, right_xiaoxi_layout;
     
     private  TextView text;
     @Override
     protected  void  onCreate(Bundle arg0) {
         super .onCreate(arg0);
         setContentView(R.layout.main_frame_activity);
         initView();
         initEvent();
     }
     public  void  initView(){
             testFragment =  new  TestFragment();
             FragmentManager fragmentManager = getSupportFragmentManager();
             FragmentTransaction f_transaction = fragmentManager.beginTransaction();
             f_transaction.replace(R.id.main_content_frame_parent, testFragment);
             f_transaction.commitAllowingStateLoss();
             initLeftLayout();
             initRightLayout();
     }
     public  void  initLeftLayout(){
         drawerLayout = (DrawerLayout) findViewById(R.id.main_drawer_layout);
         //设置透明
         drawerLayout.setScrimColor( 0x00000000 );
         //左边菜单
         left_menu_layout = (RelativeLayout) findViewById(R.id.main_left_drawer_layout);
         View view2 = getLayoutInflater().inflate(R.layout.menu_layout,  null );
         text=(TextView)view2.findViewById(R.id.text);
         text.setText( "左边测试菜单" );
         left_menu_layout.addView(view2);
     }
     public  void  initRightLayout(){
         //左边菜单
         right_xiaoxi_layout = (RelativeLayout) findViewById(R.id.main_right_drawer_layout);
         View view = getLayoutInflater().inflate(R.layout.xiaoxi_layout,  null );
         text=(TextView)view.findViewById(R.id.text);
         text.setText( "右边测试菜单" );
         right_xiaoxi_layout.addView(view);
     }
     private  void  initEvent() {
         drawerbar =  new  ActionBarDrawerToggle( this , drawerLayout, R.drawable.ic_launcher, R.string.open, R.string.close) {
                 //菜单打开
             @Override
             public  void  onDrawerOpened(View drawerView) {
                 
                 super .onDrawerOpened(drawerView);
             }
                        // 菜单关闭
             @Override
             public  void  onDrawerClosed(View drawerView) {
 
                 super .onDrawerClosed(drawerView);
             }
         };
         drawerLayout.setDrawerListener(drawerbar);
     }
         //左边菜单开关事件
     public  void  openLeftLayout() {
         if  (drawerLayout.isDrawerOpen(left_menu_layout)) {
             drawerLayout.closeDrawer(left_menu_layout);
         else  {
             drawerLayout.openDrawer(left_menu_layout);
 
         }
     }
 
     // 右边菜单开关事件
     public  void  openRightLayout() {
         if  (drawerLayout.isDrawerOpen(right_xiaoxi_layout)) {
             drawerLayout.closeDrawer(right_xiaoxi_layout);
         else  {
             drawerLayout.openDrawer(right_xiaoxi_layout);
         }
     }
}

   代码很简单,相应的地方都有注释。这里就不罗嗦了。

   主要说一下:抽屉菜单的开关事件就是,把抽屉视图添加到ActionBarDrawerToggle开关中,通关它的开关事件来控制菜单的打开和关闭,同样,一个菜单需要注册一个事件,两个菜单,也是把菜单加到这个ActionBarDrawerToggle 中进行管理。它会自行处理左右两个菜单的打开和关闭,而不会出现同时打开的现象,这一点这个控件设计的还是挺棒的。

   余下的工作,就是大家根据自己的需要,自己写左右菜单里面的内容和事件了。另外,以前看到一个帖子说,在DrawerLayout中使用listview,listview会无效,这个说法好像是不成立的,至少,在我们的项目中,菜单中添加listview或者其他常用控件,点击事件都不会受到影响。

   相关的代码我添加在了附件中,感兴趣的朋友,可以下载互相学习一下。