###侧滑菜单的两种实现

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

###使用DrawerLayout实现侧滑

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#D197F2"app:title="我是标题"app:titleTextColor="#fff"/><android.support.v4.widget.DrawerLayoutandroid:id="@+id/drawer"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="内容"/></LinearLayout><LinearLayoutandroid:layout_width="200dp"android:layout_height="match_parent"android:layout_gravity="start"android:background="@android:color/holo_blue_light"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="侧滑菜单1"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="侧滑菜单2"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="侧滑菜单3"/></LinearLayout></android.support.v4.widget.DrawerLayout></LinearLayout>
复制代码

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

这样就可以完成了一个基本的侧滑效果。

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

public DrawerLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mLeftCallback = new ViewDragCallback(Gravity.LEFT);mRightCallback = new ViewDragCallback(Gravity.RIGHT);mLeftDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mLeftCallback);mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);mLeftDragger.setMinVelocity(minVel);mLeftCallback.setDragger(mLeftDragger);
}
复制代码

####利用DrawerLayout的监听实现一些效果

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

toolbar = (Toolbar) findViewById(R.id.toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer);ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
toggle.syncState();drawer.addDrawerListener(toggle);
复制代码

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

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

@Override
public void onDrawerSlide(View drawerView, float slideOffset) {setPosition(Math.min(1f, Math.max(0, slideOffset)));
}
复制代码

setPosition的实现如下:

private void setPosition(float position) {if (position == 1f) {mSlider.setVerticalMirror(true);} else if (position == 0f) {mSlider.setVerticalMirror(false);}mSlider.setProgress(position);
}
复制代码

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

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

drawer.addDrawerListener(new DrawerLayout.DrawerListener() {@Overridepublic void onDrawerStateChanged(int newState) {// 状态发生改变}@Overridepublic void onDrawerSlide(View drawerView, float slideOffset) {// 滑动的过程当中不断地回调 slideOffset:0~1View content = drawer.getChildAt(0);float scale = 1 - slideOffset;//1~0float leftScale = (float) (1 - 0.3 * scale);float rightScale = (float) (0.7f + 0.3 * scale);//0.7~1drawerView.setScaleX(leftScale);//1~0.7drawerView.setScaleY(leftScale);//1~0.7content.setScaleX(rightScale);content.setScaleY(rightScale);content.setTranslationX(drawerView.getMeasuredWidth() * (1 - scale));//0~width}@Overridepublic void onDrawerOpened(View drawerView) {// 打开}@Overridepublic void onDrawerClosed(View drawerView) {// 关闭}
});
复制代码

###使用DrawerLayout+NavigationView实现侧滑

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

<android.support.v4.widget.DrawerLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/drawer"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 内容部分 --><FrameLayoutandroid:id="@+id/fl"android:layout_width="fill_parent"android:layout_height="fill_parent"/><!-- 菜单部分 --><android.support.design.widget.NavigationViewandroid:id="@+id/nav_view"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="start"app:headerLayout="@layout/navigation_headerlayout"app:menu="@menu/navigation_menu"/></android.support.v4.widget.DrawerLayout>
复制代码

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_icon"android:layout_width="70dp"android:layout_height="70dp"android:layout_marginTop="20dp"android:src="@drawable/icon_people"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="璐宝宝"android:textSize="20sp"/></LinearLayout>
复制代码

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

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/action_gallery"android:icon="@android:drawable/ic_menu_gallery"android:orderInCategory="100"android:title="相册"/><itemandroid:id="@+id/action_details"android:icon="@android:drawable/ic_menu_info_details"android:orderInCategory="100"android:title="详情"/><itemandroid:id="@+id/action_about"android:icon="@android:drawable/ic_menu_help"android:orderInCategory="100"android:title="关于"/><itemandroid:id="@+id/action_music"android:icon="@android:drawable/ic_menu_more"android:orderInCategory="100"android:title="音乐"><menu><itemandroid:id="@+id/action_play"android:icon="@android:drawable/ic_media_play"android:title="播放"/><itemandroid:id="@+id/action_pause"android:icon="@android:drawable/ic_media_pause"android:title="暫停"/></menu></item></menu>
复制代码

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

nav_view = (NavigationView) findViewById(R.id.nav_view);
drawer = (DrawerLayout) findViewById(R.id.drawer);
nav_view.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {@Overridepublic boolean onNavigationItemSelected(@NonNull MenuItem item) {Toast.makeText(NavigationViewActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();drawer.closeDrawer(nav_view);return false;}
});nav_view.getHeaderView(0).findViewById(R.id.iv_icon).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(NavigationViewActivity.this, "点击了头部的图标", Toast.LENGTH_SHORT).show();drawer.closeDrawer(nav_view);}
});
复制代码

如果觉得我的文字对你有所帮助的话,欢迎关注我的公众号:

我的群欢迎大家进来探讨各种技术与非技术的话题,有兴趣的朋友们加我私人微信huannan88,我拉你进群交(♂)流(♀)

Android UI进阶之旅3 Material Design之侧滑菜单的两种实现相关推荐

  1. Android UI进阶之旅9 Material Design之沉浸式设计

    ###沉浸式设计基本概念 官方的沉浸式Translucent定义:就是让整个APP沉浸(充斥了整个屏幕)在屏幕里面,没有显示状态栏,甚至没有显示底部导航栏. 平时大家所讨论的沉浸式:比如QQ的顶部To ...

  2. Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比

    Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比 标签: AndroidAsyncTaskThreadPool异步加载view 2 ...

  3. android开发 实现动态获得app的cpu占有率并导出文件的两种方法。

    android开发 实现动态获得app的cpu占有率并导出文件的两种方法. 最近在做学校实验室的项目的时候,师兄要求我对app的性能进行评估,主要是从电量.cpu占有率.python模型的响应时间三者 ...

  4. Android - 基于Toolbar的Navigation Drawer(Material Design)

    Material Design已经推出许久,有许多app都已经跟进了,这里也介绍下基于Toolbar的Navigation Drawer是如何实现的. 样式: 实现过程: 1. 在 activity_ ...

  5. android 按钮带图标 阴影_Android Material Design系列之FloatingActionButton和Snackbar

    今天主讲的Material Design系列的两个控件都不难,所以一起讲了,分别是FloatingActionButton和Snackbar.这个系列都是主讲的Material Design风格的控件 ...

  6. 开启Fluter基础之旅三-------Material Design风格组件、Cupertino风格组件、Flutter页面布局篇...

    Material Design风格组件: 继续接着上一次https://www.cnblogs.com/webor2006/p/12545701.html的Material Design进行学习. A ...

  7. android 主流开发框架,Android 9个目前流行的Material Design前端框架

    相关阅读: 吊炸天!74款APP完整源码! 其中daemonite可以直接在github上下载,用firefox或者chrome打开index.html就可以看到效果了,简直是惊艳. 9个目前流行的M ...

  8. android UI进阶之实现listview的分页加载

    上篇博文和大家分享了下拉刷新,这是一个用户体验非常好的操作方式.新浪微薄就是使用这种方式的典型. 还有个问题,当用户从网络上读取微薄的时候,如果一下子全部加载用户未读的微薄这将耗费比较长的时间,造成不 ...

  9. Android UI开发第二十七篇——实现左右划出菜单

    年前就想写左右滑动菜单,苦于没有时间,一直拖到现在,这篇代码实现参考了网上流行的SlidingMenu,使用的FrameLayout布局,不是扩展的HorizontalScrollView. 程序中自 ...

最新文章

  1. MapReduce实现join操作
  2. NumPy之:理解广播
  3. 理正地基基础计算机辅助设计的英文缩写,理正基础CAD软件介绍理正基础CAD软件介绍.pdf...
  4. 马昕璐201771010118《面向对象程序设计(java)》第七周学习总结
  5. iOS 10 的坑:新机首次安装 app,请求网络权限“是否允许使用数据”(转)
  6. 有钱男人更看重女人的美貌还是年轻?
  7. AFNetWorking网络库教程
  8. BBS论坛系统需求说明书
  9. 每日一书丨尼克新书《人工智能简史》全新升级 全方位解读AI历史和未来
  10. 计算机 审计追踪功能,第 讲 审计追踪技术与Windows安全审计功能
  11. JUC学习 - 原子操作增强类LongAdder、LongAccumulator
  12. 美国某超市销售数据分析
  13. 区块链软件开发艺术品交易平台开发NFT交易平台开发铸造源代码案例分享
  14. Java 后端服务的跨域处理
  15. avi文件格式详解(三)
  16. 六年的计算机电源坏啦,电脑电源坏了有什么症状
  17. 查询员工的薪水涨幅情况
  18. 学习编程过程中-->遇到的错误
  19. excel数据处理_Excel数据处理(1):千分位分隔符
  20. 【git】eclipse使用git的过程中的问题,提示rejected - non-fast-forward错误的解决办法

热门文章

  1. MySQL中table_schema的基本操作
  2. spring学习--AOP术语
  3. python上传大文件s3_aws s3上传大文件的4种方法
  4. Smoke Test Ad hoc Test
  5. 磁盘格式 mac android,MacDroid for mac(安卓手机数据传输助手)
  6. c#加mysql简单系统_visual studio2019连接MYSQL数据库详细教程(C#代码)
  7. 计算机建模报告,计算机三维建模及分析实验报告单.doc
  8. 质量和品质的区别_质量体系认证,与产品质量认证的区别 !
  9. android p获取通话记录_Android 底层的进程间同步机制
  10. python工作目录,如何使用python 3获取当前工作目录?