您的位置:首页 > 移动开发 > Android开发

Android侧滑菜单栏简单实现

2014-07-14 20:50 405 查看
昨天分析了android的触摸消息的传递机制,今天来实现一个简单的滑动菜单栏的滑动布局。虽然实现起来简单,但是也够用了。

我已经把工程demo上传了,需要的可以直接下载。

下面就来说说如何实现。

首先,我选择一个普通的FrameLayout作为根节点,并在其下又放置了两个FrameLayout(其中一个是我们自己写的实现了滑动的FrameLayout),布局代码如下:

<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/FrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<FrameLayout
android:id="@+id/content_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#111122">
<LinearLayout
android:id="@+id/content_test_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/content_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestButton"/>
</LinearLayout>

</FrameLayout>

<com.slindingmenu.glf.SlidingMenuLayout
android:id="@+id/sliding_menu"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/sliding_menu_content"
android:orientation="vertical"
android:layout_width="@dimen/sliding_menu_width"
android:layout_height="match_parent"
android:background="#9999AA">
<Button
android:id="@+id/sliding_menu_content_btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"/>
</LinearLayout>
</com.slindingmenu.glf.SlidingMenuLayout>

</FrameLayout>



这里要注意作为滑动菜单的com.slidingmenu.glf.SlidingMenuLayout必须要放在最后,在FrameLayout中,最后放置的布局会在FrameLayout的最上层,最先接收到触摸事件,所以一切触摸事件都会首先被我们的滑动菜单布局类所捕获,如果滑动菜单不处理,才会被主界面上的按钮等获取。

我们的侧滑菜单实现与一般的不太一样,有两种侧滑菜单:一种是侧滑后会将主界面内容推开,一种是侧滑出来后菜单会直接盖在主界面内容上。我们实现的是后一种。如果手指从界面的最左边向右划,则呼出菜单,然后左划会隐藏菜单。

具体做法可以参考代码,这里把关键的几点说一下:

每个View类都有一个computeScroll()方法,该方法控制各个View的滑动,配合Scroller类可以很容易地控制

<span style="font-size:14px;">	@Override
public void computeScroll() {//每次发生重绘该方法都会被调用
// TODO Auto-generated method stub
if(mScroller.computeScrollOffset()){//computeScrollOffset()方法返回一个boolean,当Scroller所管理的位置改变时返回true
scrollTo(mScroller.getCurrX(), 0);//菜单滑动到mScroller的当前位置,该位置由Scroller类管理。调用Scroller的startScroll或者setFinalX方法可以改变该值,在调用这两个方法后需要重绘以使computeScroll方法被调用,从而进入到这一行代码,使菜单在水平方向滑动。
postInvalidate();//重绘
}
super.computeScroll();
}</span>
这里,使用了一个辅助方法来消除重复代码,进行菜单的滚入和滚出

private void scroll(boolean isScrollingOut){
Log.e("---", ""+(-mSlidingMenuWidth-mScroller.getCurrX()));
if(isScrollingOut){//外滚
mScroller.startScroll(mScroller.getCurrX(), mScroller.getCurrY(), -mScroller.getCurrX(), 0);
postInvalidate();
isOut=true;
}else{//回滚
mScroller.startScroll(mScroller.getCurrX(), mScroller.getCurrY(), mSlidingMenuWidth-mScroller.getCurrX(), 0);
postInvalidate();
isOut=false;
}
}
上面通过调用startScroll(起始位置X坐标,起始位置Y坐标,X方向滚动距离,Y方向滚动距离,滚动开始到完成的时间) 方法配合computeScroll方法来使菜单在250ms内滚动至指定位置(不设置滚动开始到完成的时间则为默认的250ms)。

此外,对于手指的滑动,菜单也会做出相应,菜单的位置会随着手指的移动而改变,并根据手指抬起前的方向决定是呼出还是隐藏,这是通过对手势的相应完成的。为了简化手势的判断,使用了一个GestureDetector类,该类基本接管了onTouchEvent事件,并在该类的两个方法onFling和onScroll中实现上述功能:

<span style="white-space:pre">		</span>@Override
public boolean onFling(MotionEvent ev1, MotionEvent ev2, float dx, float dy) {
Log.e("---", "onFling");
if(dx>0)//手指是往外划呼出菜单还是往回划隐藏菜单
isFlingOut=true;
else
isFlingOut=false;
if(!isOut&&isFlingOut){//如果菜单没有被弹出,并且用户手指滑动呼出菜单
scroll(isFlingOut);//菜单弹出
handler.onSlidingOut();
}
if(isOut&&!isFlingOut){//菜单已经弹出而用户滑回菜单
scroll(isFlingOut);//菜单隐藏
handler.onSlidingBack();
}
return false;
}
<pre name="code" class="java">		@Override
public boolean onScroll(MotionEvent ev1, MotionEvent ev2, float dx, float dy) {
//scrollBy((int) dx, 0);
mScroller.setFinalX((int) (mScroller.getCurrX()+dx));//使菜单随手指移动而改变位置
postInvalidate();
return false;
}




其他的应该很好看懂,就不说了,第一次在CSDN上分享心得,如果有问题欢迎指出和交流

工程已经上传是用Eclipse adt写的,应该是大家最常用的
http://download.csdn.net/detail/u011249211/7635157
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐