SlidingMenu源码解析及简单应用案例
2015-11-16 11:43
429 查看
网上很多菜单框架,但应用最多,最经典的应该还是SlidingMenu,工作项目中也一直在用,所以决定研究一下;刚开始学习写博客,主要用于自己知识整理,及对问题解决的记录积累,请大神们多指点;很多内容也是参考很多好的博客总结的。
1.功能介绍
SlidingMenu是一个强大的侧滑菜单导航框架,已经被很多大牛App使用,主要特点:
(1)侧边栏是一个Fragment,可包含任何View
(2)使用简单,支持左右滑动,及很多监听效果等
(3)可自定义侧边栏显示动画
(4)可一根据自己需求改变样式(仿QQ5.0侧滑效果也没有问题。最后我会给出实现方法,只需简单的几行代码)
2.总体设计
总体主要又三个类组成。
(1)SlidingMenu继承自RelativeLayout,对外暴露API给用户,同时再添加CustomViewAbove和CustomViewBehind
(2)CustomViewAbove继承自ViewGroup,主要用来处理触摸屏事件
(3)CustomViewBehind继承自ViewGroup,主要用来配置参数,显示侧边栏的Menu部门
3.流程图
CustomViewAbove事件处理流程图,主要处理touch事件
4.类关系图
4.1类关系图
4.2核心类功能介绍
4.2.1 SlidingMenu.java
继承自RelativeLayout,对外提供API,用于配置侧边栏的侧滑模式,触屏模式,阴影,渐变及滑动效果等。
构造器中主要初始化了mViewBehind,mViewAbove及一些属性。
主要看attachToActivity方法
SlidingMenu常用属性设置:
// 设置侧边, 必须为 LEFT(左边),RIGHT(右边),LEFT_RIGHT(左右两边)三者之一
public void setMode(int mode)
// 设置触摸方式,必须为 TOUCHMODE_FULLSCREEN(全屏可触摸),TOUCHMODE_MARGIN(边缘可触摸),默认 48dp, TOUCHMODE_NONE(不可触摸)三者之一
public void setTouchModeAbove(int i)
// 根据资源文件 ID 设置阴影部分的 width
public void setShadowWidthRes(int resId)
// 根据资源文件 ID 设置阴影部分的效果
public void setShadowDrawable(int resId)
// 根据资源文件 ID 设置第二个侧边栏阴影部分的效果
public void setSecondaryShadowDrawable(int resId)
// 根据资源文件 ID 设置主界面距离屏幕的偏移量,也就是menu划出时主页面显示的剩余宽度
public void setBehindOffsetRes(int resID)
//设置SlidingMenu菜单的宽度
menu.setBehindWidth(400);
// 设置 fade in 和 fade out 效果的值
public void setFadeDegree(float f)
// 设置滑动比例的值,范围为 0-1 之间
public void setBehindScrollScale(float f)
// 根据资源文件 ID 设置侧边栏布局
public void setMenu(int res)
// 根据 View 设置侧边栏布局
public void setMenu(View v)
// 根据资源文件 ID 设置第二个侧边栏布局
public void setSecondaryMenu(int res)
// 根据 View 设置第二个侧边栏布局
public void setSecondaryMenu(View v)
// 打开菜单
public void showMenu()
// 打开第二个菜单
public void showSecondaryMenu()
// SlidingMenu 的开关
public void toggle()
// 检查侧边栏是否打开
public boolean isMenuShowing()
// 检查第二个侧边栏是否打开
public boolean isSecondaryMenuShowing()
//监听slidingmenu打开
menu.setOnOpenListener(onOpenListener);
关于关闭menu有两个监听,简单的来说,对于menu close事件,一个是when,一个是after
//监听slidingmenu关闭时事件
menu.OnCloseListener(OnClosedListener);
//监听slidingmenu关闭后事件
menu.OnClosedListener(OnClosedListener);
4.2.2CustomViewBehind.java
主要属性
// 画阴影部分
public void drawShadow(View content, Canvas canvas)
// 根据 openPercent 画 fade in/out 效果
public void drawFade(View content, Canvas canvas, float openPercent)
最后,实现下面这样QQ5.0效果的侧滑,其实很简单只需要几行代码
(是我工作中代码片段,主要实现的代码就是红色部分)
效果图:(由于不会弄gift的图片,所有图片来自鸿洋大神的 博客中,鸿洋大神也曾讲过类似的实现,从中也学到不少东西)
1.功能介绍
SlidingMenu是一个强大的侧滑菜单导航框架,已经被很多大牛App使用,主要特点:
(1)侧边栏是一个Fragment,可包含任何View
(2)使用简单,支持左右滑动,及很多监听效果等
(3)可自定义侧边栏显示动画
(4)可一根据自己需求改变样式(仿QQ5.0侧滑效果也没有问题。最后我会给出实现方法,只需简单的几行代码)
2.总体设计
总体主要又三个类组成。
(1)SlidingMenu继承自RelativeLayout,对外暴露API给用户,同时再添加CustomViewAbove和CustomViewBehind
(2)CustomViewAbove继承自ViewGroup,主要用来处理触摸屏事件
(3)CustomViewBehind继承自ViewGroup,主要用来配置参数,显示侧边栏的Menu部门
3.流程图
CustomViewAbove事件处理流程图,主要处理touch事件
4.类关系图
4.1类关系图
4.2核心类功能介绍
4.2.1 SlidingMenu.java
继承自RelativeLayout,对外提供API,用于配置侧边栏的侧滑模式,触屏模式,阴影,渐变及滑动效果等。
构造器中主要初始化了mViewBehind,mViewAbove及一些属性。
主要看attachToActivity方法
public void attachToActivity(Activity activity, int slideStyle, boolean actionbarOverlay) { ... ... ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView(); ViewGroup decorChild = (ViewGroup) decor.getChildAt(0); // save ActionBar themes that have transparent assets decorChild.setBackgroundResource(background); decor.removeView(decorChild); decor.addView(this); setContent(decorChild); break; ... ... }这里slideStyle选取SLIDING_WINDOW的case进行分析,看到主要是获取decorView,将decorView下面的decorChild(我们的根布局)移除,把SlidingMenu添加进来,把decorChild赋值给mViewAbove。(SLIDING_CONTENT的原理差不多)
SlidingMenu常用属性设置:
// 设置侧边, 必须为 LEFT(左边),RIGHT(右边),LEFT_RIGHT(左右两边)三者之一
public void setMode(int mode)
// 设置触摸方式,必须为 TOUCHMODE_FULLSCREEN(全屏可触摸),TOUCHMODE_MARGIN(边缘可触摸),默认 48dp, TOUCHMODE_NONE(不可触摸)三者之一
public void setTouchModeAbove(int i)
// 根据资源文件 ID 设置阴影部分的 width
public void setShadowWidthRes(int resId)
// 根据资源文件 ID 设置阴影部分的效果
public void setShadowDrawable(int resId)
// 根据资源文件 ID 设置第二个侧边栏阴影部分的效果
public void setSecondaryShadowDrawable(int resId)
// 根据资源文件 ID 设置主界面距离屏幕的偏移量,也就是menu划出时主页面显示的剩余宽度
public void setBehindOffsetRes(int resID)
//设置SlidingMenu菜单的宽度
menu.setBehindWidth(400);
// 设置 fade in 和 fade out 效果的值
public void setFadeDegree(float f)
// 设置滑动比例的值,范围为 0-1 之间
public void setBehindScrollScale(float f)
// 根据资源文件 ID 设置侧边栏布局
public void setMenu(int res)
// 根据 View 设置侧边栏布局
public void setMenu(View v)
// 根据资源文件 ID 设置第二个侧边栏布局
public void setSecondaryMenu(int res)
// 根据 View 设置第二个侧边栏布局
public void setSecondaryMenu(View v)
// 打开菜单
public void showMenu()
// 打开第二个菜单
public void showSecondaryMenu()
// SlidingMenu 的开关
public void toggle()
// 检查侧边栏是否打开
public boolean isMenuShowing()
// 检查第二个侧边栏是否打开
public boolean isSecondaryMenuShowing()
//监听slidingmenu打开
menu.setOnOpenListener(onOpenListener);
关于关闭menu有两个监听,简单的来说,对于menu close事件,一个是when,一个是after
//监听slidingmenu关闭时事件
menu.OnCloseListener(OnClosedListener);
//监听slidingmenu关闭后事件
menu.OnClosedListener(OnClosedListener);
4.2.2CustomViewBehind.java
主要属性
/** 第一个侧边栏,一般为左边栏 */ private View mContent; /** 第二个侧边栏,一般为右边栏 */ private View mSecondaryContent; /** 滑动侧边栏的最大临界值在设置 TOUCHMODE_MARGIN 起作用,默认 48dp */ private int mMarginThreshold; /** 侧边栏被滑出后,主界面留在屏幕上的 offset */ private int mWidthOffset; /** 有三个值可以选,LEFT/RIGHT/LEFT_RIGHT */ private int mMode; /** 侧边栏在侧滑过程中是否需要 fade 动画效果 */ private boolean mFadeEnabled; /** 定义滑动比例的值,范围 0-1f */ private float mScrollScale; /** 侧边栏滑出后的阴影部分,demo 中用的是 Gradient */ private Drawable mShadowDrawable; /** 同上,为第二个侧边栏的阴影部分 */ private Drawable mSecondaryShadowDrawable; /** 阴影部分的宽 */ private int mShadowWidth; /** 侧边栏滑动过程中 fade 动画的值,范围 0-1f */ private float mFadeDegree;在侧边栏滑动过程中, 通过回调 CustomViewAbove 的 dispatchDraw 方法画阴影部分和 fade in/out 效果。
// 画阴影部分
public void drawShadow(View content, Canvas canvas)
// 根据 openPercent 画 fade in/out 效果
public void drawFade(View content, Canvas canvas, float openPercent)
最后,实现下面这样QQ5.0效果的侧滑,其实很简单只需要几行代码
(是我工作中代码片段,主要实现的代码就是红色部分)
// 实例化滑动菜单对象 SlidingMenu sm = getSlidingMenu(); // 设置可以左右滑动的菜单 sm.setMode(SlidingMenu.LEFT); sm.setBehindWidthRes(R.dimen.left_menu_width); sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE); sm.setFadeDegree(0.25f); sm.setBehindScrollScale(0.25f); sm.setFadeEnabled(false); sm.setBackgroundImage(R.drawable.bg_menu_top); <span style="color:#FF0000;"> sm.setBehindCanvasTransformer(new SlidingMenu.CanvasTransformer() { @Override public void transformCanvas(Canvas canvas, float percentOpen) { float scale = (float) (percentOpen * 0.25 + 0.75); canvas.scale(scale, scale, -canvas.getWidth() / 2, canvas.getHeight() / 2); } }); sm.setAboveCanvasTransformer(new SlidingMenu.CanvasTransformer() { @Override public void transformCanvas(Canvas canvas, float percentOpen) { float scale = (float) (1 - percentOpen * 0.25); canvas.scale(scale, scale, 0, canvas.getHeight() / 2); } });</span> sm.setOnCloseListener(new SlidingMenu.OnCloseListener() { @Override public void onClose() { isPopTitleOpen = false; iv_alpha.setVisibility(View.INVISIBLE); if (mRlPopTitle != null && pageIndex == 0) { mRlPopTitle.setVisibility(View.VISIBLE); } else { mRlPopTitle.setVisibility(View.INVISIBLE); } } }); sm.setOnOpenedListener(new SlidingMenu.OnOpenedListener() { @Override public void onOpened() { isPopTitleOpen = true; if (mRlPopTitle != null) { mRlPopTitle.setVisibility(View.INVISIBLE); } } }); sm.setOnOpenListener(new SlidingMenu.OnOpenListener() { @Override public void onOpen() { isPopTitleOpen = true; if (mRlPopTitle != null) { mRlPopTitle.setVisibility(View.INVISIBLE); } } }); setBehindContentView(R.layout.menu_frame_left);实现思路:主要就是给AboveView的尺寸重试画一个尺寸。
效果图:(由于不会弄gift的图片,所有图片来自鸿洋大神的 博客中,鸿洋大神也曾讲过类似的实现,从中也学到不少东西)
相关文章推荐
- 有梦就放开去追
- 使用注解实现AOP
- 程序包com.sun.image.codec.jpeg不存在 问题的完美解决
- 《如何及时处理你的坏心情》第二章:我们所担心的事情,99%是不会发生的
- ThreadPoolExecutor运转机制详解
- Linux-GLIBCXX版本过低导致编译错误--version `GLIBCXX_3.4.20' not found
- 各种 SDk
- Spring常用注解,自动扫描装配Bean
- 过滤dt中重复的记录
- 关于线程变量的应用
- 使用docker构建云服务器项目
- Codeforces 596A B C Codeforces Round #331 A B C
- LeetCode---First Bad Version
- jquery实践案例--验证电子邮箱
- 理解输入输出流
- Spring MVC 入门分析
- 关于mpls和ns3
- CSS背景图拉伸自适应尺寸,全浏览器兼容
- 跟我学习javascript的函数调用和构造函数调用
- krpanotools基本操作