当前位置:   article > 正文

两种方式实现Android侧滑菜单_android 侧滑菜单实现

android 侧滑菜单实现

侧滑菜单的两种实现

  1. 使用DrawerLayout,灵活度比较高。
  2. 使用DrawerLayout+NavigationView,这是谷歌对Material Design的一种标准化。

使用DrawerLayout实现侧滑

首先,我们需要一个布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical">
  8. <android.support.v7.widget.Toolbar
  9. android:id="@+id/toolbar"
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content"
  12. android:background="#D197F2"
  13. app:title="标题"
  14. app:titleTextColor="#fff"/>
  15. <android.support.v4.widget.DrawerLayout
  16. android:id="@+id/drawer"
  17. android:layout_width="match_parent"
  18. android:layout_height="match_parent">
  19. <LinearLayout
  20. android:layout_width="match_parent"
  21. android:layout_height="match_parent"
  22. android:orientation="vertical">
  23. <TextView
  24. android:layout_width="match_parent"
  25. android:layout_height="wrap_content"
  26. android:text="内容"/>
  27. </LinearLayout>
  28. <LinearLayout
  29. android:layout_width="200dp"
  30. android:layout_height="match_parent"
  31. android:layout_gravity="start"
  32. android:background="@android:color/holo_blue_light"
  33. android:orientation="vertical">
  34. <TextView
  35. android:layout_width="match_parent"
  36. android:layout_height="wrap_content"
  37. android:text="侧滑菜单1"/>
  38. <TextView
  39. android:layout_width="match_parent"
  40. android:layout_height="wrap_content"
  41. android:text="侧滑菜单2"/>
  42. <TextView
  43. android:layout_width="match_parent"
  44. android:layout_height="wrap_content"
  45. android:text="侧滑菜单3"/>
  46. </LinearLayout>
  47. </android.support.v4.widget.DrawerLayout>
  48. </LinearLayout>


这个布局侧滑菜单包括了菜单部分以及内容部分,用DrawerLayout来包裹起来。其中,菜单部分的根布局需要添加android:layout_gravity="start",如果是右滑的话,改为end即可。这样就可以完成了一个基本的侧滑效果。

DrawerLayout的实现其实是通过ViewDragHelper来实现的,DrawerLayout构造函数的相关代码如下:

  1. public DrawerLayout(Context context, AttributeSet attrs, int defStyle) {
  2. super(context, attrs, defStyle);
  3. mLeftCallback = new ViewDragCallback(Gravity.LEFT);
  4. mRightCallback = new ViewDragCallback(Gravity.RIGHT);
  5. mLeftDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mLeftCallback);
  6. mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
  7. mLeftDragger.setMinVelocity(minVel);
  8. mLeftCallback.setDragger(mLeftDragger);
  9. }

利用DrawerLayout的监听实现一些效果
例如,我们可以实现侧滑的时候,Toolbar左上角的按钮实时变化,我们可以添加一个监听ActionBarDrawerToggle:

  1. toolbar = (Toolbar) findViewById(R.id.toolbar);
  2. drawer = (DrawerLayout) findViewById(R.id.drawer);
  3. ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
  4. toggle.syncState();
  5. drawer.addDrawerListener(toggle);

下面我们分析一下实现原理:

其中,ActionBarDrawerToggle实现了DrawerLayout.DrawerListener。并且在滑动的过程中不断 刷新左上角的Drawerable:

  1. @Override
  2. public void onDrawerSlide(View drawerView, float slideOffset) {
  3. setPosition(Math.min(1f, Math.max(0, slideOffset)));
  4. }
setPosition的实现如下:

  1. private void setPosition(float position) {
  2. if (position == 1f) {
  3. mSlider.setVerticalMirror(true);
  4. } else if (position == 0f) {
  5. mSlider.setVerticalMirror(false);
  6. }
  7. mSlider.setProgress(position);
  8. }

其实就是在滑动的过程中不断改变mSlider(一个自定义Drawerable对象)的Progress,从而不断刷新状态。

因此,我们可以做一些自定义的特效,例如侧滑的时候缩放、平移:

  1. drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
  2. @Override
  3. public void onDrawerStateChanged(int newState) {
  4. // 状态发生改变
  5. }
  6. @Override
  7. public void onDrawerSlide(View drawerView, float slideOffset) {
  8. // 滑动的过程当中不断地回调 slideOffset:0~1
  9. View content = drawer.getChildAt(0);
  10. float scale = 1 - slideOffset;//1~0
  11. float leftScale = (float) (1 - 0.3 * scale);
  12. float rightScale = (float) (0.7f + 0.3 * scale);//0.7~1
  13. drawerView.setScaleX(leftScale);//1~0.7
  14. drawerView.setScaleY(leftScale);//1~0.7
  15. content.setScaleX(rightScale);
  16. content.setScaleY(rightScale);
  17. content.setTranslationX(drawerView.getMeasuredWidth() * (1 - scale));//0~width
  18. }
  19. @Override
  20. public void onDrawerOpened(View drawerView) {
  21. // 打开
  22. }
  23. @Override
  24. public void onDrawerClosed(View drawerView) {
  25. // 关闭
  26. }
  27. });

使用DrawerLayout+NavigationView实现侧滑

同样道理,我们需要一个布局,同样的,用DrawerLayout进行包裹内容以及菜单,其中菜单是一个NavigationView,可以指定头部以及菜单部分,并且提供一些属性的设置。(可以看出来,使用NavigationView的灵活度比较差,如果项目是直接使用这种模板的话,可以直接使用,不然的话我们还是使用一般的方式去实现)

  1. <android.support.v4.widget.DrawerLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. android:id="@+id/drawer"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent">
  7. <!-- 内容部分 -->
  8. <FrameLayout
  9. android:id="@+id/fl"
  10. android:layout_width="fill_parent"
  11. android:layout_height="fill_parent"/>
  12. <!-- 菜单部分 -->
  13. <android.support.design.widget.NavigationView
  14. android:id="@+id/nav_view"
  15. android:layout_width="wrap_content"
  16. android:layout_height="match_parent"
  17. android:layout_gravity="start"
  18. app:headerLayout="@layout/navigation_headerlayout"
  19. app:menu="@menu/navigation_menu"/>
  20. </android.support.v4.widget.DrawerLayout>

这里我们指定了头部如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:gravity="center_horizontal"
  7. android:orientation="vertical">
  8. <ImageView
  9. android:id="@+id/iv_icon"
  10. android:layout_width="70dp"
  11. android:layout_height="70dp"
  12. android:layout_marginTop="20dp"
  13. android:src="@drawable/icon_people"/>
  14. <TextView
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:layout_marginTop="10dp"
  18. android:text="test"
  19. android:textSize="20sp"/>
  20. </LinearLayout>

菜单部分如下(menu文件夹下建立),其中菜单可以嵌套:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item
  4. android:id="@+id/action_gallery"
  5. android:icon="@android:drawable/ic_menu_gallery"
  6. android:orderInCategory="100"
  7. android:title="相册"
  8. />
  9. <item
  10. android:id="@+id/action_details"
  11. android:icon="@android:drawable/ic_menu_info_details"
  12. android:orderInCategory="100"
  13. android:title="详情"
  14. />
  15. <item
  16. android:id="@+id/action_about"
  17. android:icon="@android:drawable/ic_menu_help"
  18. android:orderInCategory="100"
  19. android:title="关于"
  20. />
  21. <item
  22. android:id="@+id/action_music"
  23. android:icon="@android:drawable/ic_menu_more"
  24. android:orderInCategory="100"
  25. android:title="音乐"
  26. >
  27. <menu>
  28. <item
  29. android:id="@+id/action_play"
  30. android:icon="@android:drawable/ic_media_play"
  31. android:title="播放"/>
  32. <item
  33. android:id="@+id/action_pause"
  34. android:icon="@android:drawable/ic_media_pause"
  35. android:title="暫停"/>
  36. </menu>
  37. </item>
  38. </menu>

到现在为止,就可以实现侧滑了,最后我们添加上对应的点击事件,然后关闭菜单:

  1. nav_view = (NavigationView) findViewById(R.id.nav_view);
  2. drawer = (DrawerLayout) findViewById(R.id.drawer);
  3. nav_view.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
  4. @Override
  5. public boolean onNavigationItemSelected(@NonNull MenuItem item) {
  6. Toast.makeText(NavigationViewActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
  7. drawer.closeDrawer(nav_view);
  8. return false;
  9. }
  10. });
  11. nav_view.getHeaderView(0).findViewById(R.id.iv_icon).setOnClickListener(new View.OnClickListener() {
  12. @Override
  13. public void onClick(View v) {
  14. Toast.makeText(NavigationViewActivity.this, "点击了头部的图标", Toast.LENGTH_SHORT).show();
  15. drawer.closeDrawer(nav_view);
  16. }
  17. });


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/314843
推荐阅读
相关标签
  

闽ICP备14008679号