在制做一个软件的时候要用到侧滑菜单(SlidMenu),而且,现在这个应用在软件开发中应用很多!虽然网上有好多说是实现了这个功能,csdn上资源下载那里也有好多提供下载,但当我一个一个的测试了之后,只能感叹一句“坑爹啊!”都是由bug的,想想还是自己来实现吧!
实现上主要就是一个自定义的MySlidView,在这个MySlidView里边去加载两个你要显示的View(mMenuView, mSlidView),即一个是滑动之后,左侧的mSlidView,另一个就是关闭mMenuView之后的mSlidView!
而菜单的打开与关闭,实际上就是操作上层的mSlidView的滑动,当需要打开菜单时,让mSlidView向右边滑动,如果要关闭menu,就再让它滑回来,
主要代码就是自定义的类:
/**
* @author Administrator
*
*/
public class MySlidView extends RelativeLayout {
private View mMenuView;
private View mSlidView;
private RelativeLayout bgShade;
private Context mContext;
private float mTouchSlop;
private Scroller mScroller; // 滑动控制
private VelocityTracker mVelocityTracker; // 用于判断甩动手势
private static final int SNAP_VELOCITY = 100; // 滑动速度阀值
private float mLastMotionX;
private float mLastMotionY;
private float mFirstMotionX;
private int menuWidth; //侧边菜单slidmenu的宽度
public int menuState; //菜单状态
private boolean mIsBeingDragged = true; // 是否在滑动
public MySlidView(Context context) {
super(context);
init(context);
}
public MySlidView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MySlidView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
/**
* @param context
* 初始化
*/
private void init(Context context) {
mContext = context;
mScroller = new Scroller(context);
menuState = ConstantQuantity.MENU_STATE_CLOSE;
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
bgShade = new RelativeLayout(context);
}
/**
* @param menu
* @param slid
*/
public void addViews(View menu, View slid) {
setMenuView(menu);
setSlidView(slid);
}
/**
* @see Android.view.View#computeScroll()
*/
@Override
public void computeScroll() {
if (!mScroller.isFinished()) {
if (mScroller.computeScrollOffset()) {
int oldX = mSlidView.getScrollX();
int x = mScroller.getCurrX();
if (oldX != x) {
if (mSlidView != null) {
mSlidView.scrollTo(mScroller.getCurrX(), 0);
bgShade.scrollTo(x + 10, 0);//
}
}
invalidate();
}
}
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
postInvalidate();
}
/**
* @see android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
* 拦截手势,在处理触屏操作之前先拦截下触屏事件进行判断之后的操作!
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
menuWidth = getMenuViewWidth();
int action = event.getAction();
float x = event.getX();
float y = event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
mFirstMotionX = x;
mLastMotionX = x;
mLastMotionY = y;
mIsBeingDragged = false;
break;
case MotionEvent.ACTION_MOVE:
float deltaX = mLastMotionX - x;
float deltaY = mLastMotionY - y;
if (Math.abs(deltaX) > mTouchSlop
&& Math.abs(deltaX) > Math.abs(deltaY)) {
float oldScrollX = mSlidView.getScrollX();
if (oldScrollX <= 0) {
mIsBeingDragged = true;
mLastMotionX = x;
} else {
if (deltaX < 0) {
mIsBeingDragged = true;
mLastMotionX = x;
}
}
}
if (menuState == ConstantQuantity.MENU_STATE_OPEN) {
System.out.println(mFirstMotionX + " ; "
+ mSlidView.getScrollX());
if (mFirstMotionX >= 0
&& mFirstMotionX < Math.abs(mSlidView.getScrollX())) {
mIsBeingDragged = false;
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (menuState == ConstantQuantity.MENU_STATE_OPEN) {
if(mFirstMotionX >= menuWidth && mLastMotionX >= menuWidth){
openMenuView();
}
}
break;
}
return mIsBeingDragged;
}