Android 实现形态各异的双向侧滑菜单 自定义控件来袭

转载请标明出处:,本文出自:【张鸿洋的博客】

1、概述

关于自定义控件侧滑已经写了两篇了~~今天决定把之前的单向改成双向,当然了,单纯的改动之前的代码也没意思,今天不仅会把之前的单向改为双向,还会多添加一种侧滑效果,给大家带来若干种形态各异的双向侧滑菜单,不过请放心,代码会很简单~~然后根据这若干种,只要你喜欢,相信你可以打造任何绚(bian)丽(tai)效果的双向侧滑菜单~~

首先回顾一下,之前写过的各种侧滑菜单,为了不占据篇幅,就不贴图片了:

1、最普通的侧滑效果,请参考:Android 自定义控件打造史上最简单的侧滑菜单

2、仿QQ5.0侧滑效果,请参考:Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭

3、菜单在内容之后的侧滑效果,请参考:Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭

2、目标效果

1、最普通的双向侧滑

是不是很模糊,嗯,没办法,电脑显卡弱。。。。

2、抽屉式双向侧滑

3、菜单在内容之下的双向侧滑

凑合看下,文章最后会提供源码下载,大家可以安装体验一下~

所有的代码的内容区域都是一个ListView,两侧菜单都包含按钮,基本的冲突都检测过~~~当然如果有bug在所难免,请直接留言;如果你解决了某些未知bug,希望你也可以留言,或许可以帮助到其他人~~

下面就开始我们的代码了。

3、代码是最好的老师1、布局文件

既然是双向菜单,那么我们的布局文件是这样的:

<com.zhy.view.BinarySlidingMenu xmlns:android=""xmlns:tools=""xmlns:zhy=""android:id="@+id/id_menu"android:layout_width="wrap_content"android:layout_height="fill_parent"android:scrollbars="none"zhy:rightPadding="100dp" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="fill_parent"android:orientation="horizontal" ><include layout="@layout/layout_menu" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:background="@drawable/eee"android:gravity="center"android:orientation="horizontal" ><ListViewandroid:id="@android:id/list"android:layout_width="fill_parent"android:layout_height="fill_parent" ></ListView></LinearLayout><include layout="@layout/layout_menu2" /></LinearLayout></com.zhy.view.BinarySlidingMenu>

最外层是我们的自定义的BinarySlidingMenu,内部一个水平方向的LinearLayout,然后是左边的菜单,内容区域,右边的菜单布局~~

关键就是我们的BinarySlidingMenu

2、BinarySlidingMenu的构造方法/** * 屏幕宽度 */private int mScreenWidth;/** * dp 菜单距离屏幕的右边距 */private int mMenuRightPadding;public BinarySlidingMenu(Context context, AttributeSet attrs, int defStyle){super(context, attrs, defStyle);mScreenWidth = ScreenUtils.getScreenWidth(context);TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.BinarySlidingMenu, defStyle, 0);int n = a.getIndexCount();for (int i = 0; i < n; i++){int attr = a.getIndex(i);switch (attr){case R.styleable.BinarySlidingMenu_rightPadding:// 默认50mMenuRightPadding = a.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50f,getResources().getDisplayMetrics()));// 默认为10DPbreak;}}a.recycle();}我们在构造方法中,获取我们自定义的一个属性rightPadding,然后赋值给我们的成员变量mMenuRightPadding;关于如何自定义属性参考侧滑菜单的第一篇博文,这里就不赘述了。3、onMeasure

onMeasure中肯定是对侧滑菜单的宽度、高度等进行设置:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){/** * 显示的设置一个宽度 */if (!once){mWrapper = (LinearLayout) getChildAt(0);mLeftMenu = (ViewGroup) mWrapper.getChildAt(0);mContent = (ViewGroup) mWrapper.getChildAt(1);mRightMenu = (ViewGroup) mWrapper.getChildAt(2);mMenuWidth = mScreenWidth – mMenuRightPadding;mHalfMenuWidth = mMenuWidth / 2;mLeftMenu.getLayoutParams().width = mMenuWidth;mContent.getLayoutParams().width = mScreenWidth;mRightMenu.getLayoutParams().width = mMenuWidth;}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}

可以看到我们分别给左侧、右侧的菜单设置了宽度(mScreenWidth – mMenuRightPadding);

宽度设置完成以后,肯定就是定位了,把左边的菜单弄到左边去,右边的菜单放置到右边,中间依然是我们的内容区域,那么请看onLayout方法~

4、onLayout@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b){super.onLayout(changed, l, t, r, b);if (changed){// 将菜单隐藏this.scrollTo(mMenuWidth, 0);once = true;}}哈,出奇的简单,因为我们的内部是个横向的线性布局,所以直接把左侧滑出去即可~~定位也完成了,那么此时应该到了我们的处理触摸了。5、onTouchEvent@Overridepublic boolean onTouchEvent(MotionEvent ev){int action = ev.getAction();switch (action){// Up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏case MotionEvent.ACTION_UP:int scrollX = getScrollX();// 如果是操作左侧菜单if (isOperateLeft){// 如果影藏的区域大于菜单一半,则影藏菜单if (scrollX > mHalfMenuWidth){this.smoothScrollTo(mMenuWidth, 0);// 如果当前左侧菜单是开启状态,且mOnMenuOpenListener不为空,则回调关闭菜单if (isLeftMenuOpen && mOnMenuOpenListener != null){// 第一个参数true:打开菜单,false:关闭菜单;第二个参数 0 代表左侧;1代表右侧mOnMenuOpenListener.onMenuOpen(false, 0);}isLeftMenuOpen = false;} else// 关闭左侧菜单{this.smoothScrollTo(0, 0);// 如果当前左侧菜单是关闭状态,且mOnMenuOpenListener不为空,则回调打开菜单if (!isLeftMenuOpen && mOnMenuOpenListener != null){mOnMenuOpenListener.onMenuOpen(true, 0);}isLeftMenuOpen = true;}}// 操作右侧if (isOperateRight){// 打开右侧侧滑菜单if (scrollX > mHalfMenuWidth + mMenuWidth){this.smoothScrollTo(mMenuWidth + mMenuWidth, 0);} else// 关闭右侧侧滑菜单{this.smoothScrollTo(mMenuWidth, 0);}}return true;}return super.onTouchEvent(ev);}

依然是简单~~~我们只需要关注ACTION_UP,然后得到手指抬起后的scrollX,然后我们通过一个布尔值,判断用户现在操作是针对左侧菜单,还是右侧菜单?

如果是操作左侧,那么判断scorllX是否超过了菜单宽度的一半,然后做相应的操作。

如果是操作右侧,那么判断scrollX与mHalfMenuWidth + mMenuWidth ( 注意下,右侧菜单完全影藏的时候,scrollX 就等于mMenuWidth ),然后做对应的操作。

我们还给左侧的菜单加上了一个回调:

人若软弱就是自己最大的敌人

Android 实现形态各异的双向侧滑菜单 自定义控件来袭

相关文章:

你感兴趣的文章:

标签云: