package com.bigdo.controls; import com.bigdo.app.R; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.RelativeLayout; import android.widget.Scroller; public class XSlidingMenu extends RelativeLayout { // private Context mContext; private Scroller mScroller; private int mTouchSlop; // 最小滑动距离 private View mleftView, mainView, mrightView;// 左中右视图 private Boolean canslideleft, HasLeftObj = false;// 左边部分能滑动 private Boolean canslideright, HasRightObj = false;// 右边部分能滑动 private int mlastX, mlastY, newx, newy; private Boolean IsScrolling;// 是否滑动 private int leftWidth, rightWidth;// 左右视图宽度 private int newScrollX; // ActionUp时mainView偏移量 private int delta_X, delta_Y; private int lastMoveState = -1, curMoveState = 0; private int duration = 400, shadow = 10; private View mainView_Content; private boolean mainTouch = true; // private Drawable mainView_bg; public XSlidingMenu(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } public XSlidingMenu(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public XSlidingMenu(Context context) { super(context); init(context); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { mainView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); if (mainView.getScrollX() == 0) { mainView_Content .setBackgroundResource(R.drawable.ra_sliding_bg); lastMoveState = -1; } postInvalidate(); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { newx = (int) ev.getX(); newy = (int) ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mlastX = newx; mlastY = newy; // 判断目前状态:左右都能滑动--初始状态 左边能滑动--左边打开状态 右边能滑动--右边打开状态 if (HasLeftObj) { leftWidth = mleftView.getWidth() - shadow; } else { leftWidth = 0; canslideleft = false; } if (HasRightObj) { rightWidth = mrightView.getWidth() - shadow; } else { rightWidth = 0; canslideright = false; } int ScrollX = mainView.getScrollX(); if (ScrollX == 0) { // 初始状态 canslideleft = HasLeftObj ? true : false; canslideright = HasRightObj ? true : false; } else if (ScrollX == -leftWidth) {// 左边打开状态 canslideleft = HasLeftObj ? true : false; canslideright = false; } else if (ScrollX == rightWidth) {// 右边打开状态 canslideleft = false; canslideright = HasRightObj ? true : false; } IsScrolling = false; // Log.v("onInterceptTouchEvent", "ActionDown IsScrolling=" // + IsScrolling); // Log.w("onInterceptTouchEvent", "left/right=" + leftWidth + "/" // + rightWidth); // Log.w("onInterceptTouchEvent", "ActionDown =" + canslideleft + // "/" // + canslideright); break; case MotionEvent.ACTION_MOVE: delta_X = Math.abs(newx - mlastX); delta_Y = Math.abs(newy - mlastY); // 超过最小滑动距离并且x方向大于y方向偏移量才拦截(ViewGroup处理) if (delta_X > mTouchSlop && delta_X > delta_Y) { IsScrolling = true; } // Log.w("onInterceptTouchEvent", "ActionMove IsScrolling=" // + IsScrolling); break; } return IsScrolling; } private void setMainOnTouch(View mainView) { // View mainViewx = mainView; if (mainView != null) { mainView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { return mainTouch; } }); } } @Override public boolean onTouchEvent(MotionEvent event) { newx = (int) event.getX(); newy = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // mlastX = newx; break; case MotionEvent.ACTION_MOVE: delta_X = Math.abs(newx - mlastX); delta_Y = Math.abs(newy - mlastY); if (delta_X > mTouchSlop && delta_X > delta_Y) { // 超过最小滑动距离并且x方向大于y方向偏移量才拦截(ViewGroup处理) IsScrolling = true; } // Log.v("onTouchEvent", "ActionMove IsScrolling=" + IsScrolling); if (IsScrolling) { int deltaX = mlastX - newx; mlastX = newx; int scrollX = mainView.getScrollX() + deltaX; // Log.v("onTouchEvent", "ActionMove c=" + canslideleft + "/" // + canslideright); // 无论目前为何种状态,滑动的话只能朝一个方向,因此先判断是否为初始状态,初始状态再依据偏移量判断向左还是向右, // 之后再处理左边或右边的滑动 if (canslideleft && canslideright) { // 判断是不是初始状态 if (deltaX > 0) { // 向左滑动 canslideleft = false; canslideright = HasRightObj ? true : false; } else if (deltaX < 0) { // 向右滑动 canslideleft = HasLeftObj ? true : false; canslideright = false; } } // Log.v("onTouchEvent", "ActionMove c0=" + canslideleft + "/" // + canslideright); if (canslideleft) { // 左边能滑动 // Log.v("onTouchEvent", "ActionMove c1=" + canslideleft + // "/" // + canslideright); if (scrollX >= 0) { scrollX = 0; } if (scrollX <= -leftWidth) { scrollX = -leftWidth; } // Log.v("onTouchEvent", "ActionMove c1完成"); curMoveState = 1; } if (canslideright) { // 右边能滑动 // Log.v("onTouchEvent", "ActionMove c2=" + canslideleft + // "/" // + canslideright); if (scrollX <= 0) { scrollX = 0; } if (scrollX >= rightWidth) { scrollX = rightWidth; } // Log.v("onTouchEvent", "ActionMove c2完成"); curMoveState = 2; } if (lastMoveState != curMoveState) { if (HasLeftObj && curMoveState == 1) { mainView_Content .setBackgroundResource(R.drawable.sliding_left); mleftView.bringToFront(); } else if (HasRightObj && curMoveState == 2) { mainView_Content .setBackgroundResource(R.drawable.sliding_right); mrightView.bringToFront(); } else { mainView_Content .setBackgroundResource(R.drawable.ra_sliding_bg); } // mainView. mainView.bringToFront(); lastMoveState = curMoveState; } if (scrollX == 0) { mainView_Content .setBackgroundResource(R.drawable.ra_sliding_bg); lastMoveState = -1; // Log.v("onTouchEvent", "-------0000" + scrollX); } mainView.scrollTo(scrollX, mainView.getScrollY()); // Log.w("mainView-scrollX", scrollX+""); } break; case MotionEvent.ACTION_UP: boolean isSetb = false; if (IsScrolling) { newScrollX = mainView.getScrollX(); int dx = 0; // Log.v("onTouchEvent", "ActionUp初始=" + newScrollX + "/" // + canslideleft + "/" + canslideright); if (newScrollX < 0 && canslideleft) {// left view Log.v("onTouchEvent", "ActionUp left=" + leftWidth); if (newScrollX <= -leftWidth / 2) { dx = -leftWidth - newScrollX; canslideleft = HasLeftObj ? true : false; canslideright = false; } else if (newScrollX > -leftWidth / 2) { dx = -newScrollX; canslideleft = HasLeftObj ? true : false; canslideright = HasRightObj ? true : false; } // Log.v("onTouchEvent", "ActionUp c0完成 " + newScrollX + "/" // + canslideleft + "/" + canslideright); smoothScrollTo(dx); isSetb = true; } if (newScrollX > 0 && canslideright) { // Log.v("onTouchEvent", "ActionUp right=" + rightWidth); if (newScrollX >= rightWidth / 2) {// right View dx = rightWidth - newScrollX; canslideleft = false; canslideright = HasRightObj ? true : false; } else if (newScrollX < rightWidth / 2) { dx = -newScrollX; canslideleft = HasLeftObj ? true : false; canslideright = HasRightObj ? true : false; } // Log.v("onTouchEvent", "ActionUp c1完成 " + newScrollX + "/" // + canslideleft + "/" + canslideright); smoothScrollTo(dx); isSetb = true; } } // Log.v("onTouchEvent", "-------222" + mainView.getScrollX()); if (!isSetb && mainView.getScrollX() == 0) { mainView_Content .setBackgroundResource(R.drawable.ra_sliding_bg); // Log.v("onTouchEvent", "-------111" + mainView.getScrollX()); postInvalidate(); } lastMoveState = -1; break; } return super.onTouchEvent(event); } void smoothScrollTo(int dx) { mScroller.startScroll(newScrollX, 0, dx, 0, duration); postInvalidate(); } private void init(Context context) { // mContext = context;android:descendantFocusability setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); mScroller = new Scroller(getContext()); mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); } public void setleftview(View view) { LayoutParams behindParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT); // behindParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); setleftview(view, behindParams); } public void setleftview(View view, int rightMargin) { LayoutParams behindParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); // behindParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); behindParams.rightMargin = rightMargin; setleftview(view, behindParams); } public void setleftview(View view, LayoutParams layoutParams) { if (layoutParams != null) { layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); } addView(view, layoutParams); mleftView = view; HasLeftObj = true; // view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), // view.getPaddingRight() + shadow, view.getPaddingBottom()); } public void setrightview(View view) { LayoutParams behindParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT); // behindParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); setrightview(view, behindParams); } public void setrightview(View view, int leftMargin) { LayoutParams behindParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); // behindParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); behindParams.leftMargin = leftMargin; setrightview(view, behindParams); } public void setrightview(View view, LayoutParams layoutParams) { if (layoutParams != null) { layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); } addView(view, layoutParams); mrightView = view; HasRightObj = true; // view.setPadding(view.getPaddingLeft() + shadow, view.getPaddingTop(), // view.getPaddingRight(), view.getPaddingBottom()); } public void setCenterView(View view) { RelativeLayout mainView_ = new RelativeLayout(this.getContext()); mainView_.setBackgroundResource(android.R.color.transparent); LayoutParams aboveParams_ = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); addView(mainView_, aboveParams_); LayoutParams aboveParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); mainView_.addView(view, aboveParams); mainView = mainView_; setMainOnTouch(view); mainView.bringToFront(); mainView_Content = view; // mainView_bg = view.getBackground(); } // 显示左边部分 public void showLeft() { if (mleftView != null) { int leftScrollX = mainView.getScrollX(); if (leftScrollX == rightWidth) { mainView_Content.setBackgroundResource(R.drawable.sliding_left); mainView.bringToFront(); mrightView.bringToFront(); mainView.bringToFront(); // 这个条件可以不要,因为这种状态showleft 已经滑出去了 mScroller.startScroll(leftScrollX, 0, -(leftWidth + rightWidth), 0, duration); postInvalidate(); } else if (leftScrollX == 0) { mainView_Content.setBackgroundResource(R.drawable.sliding_left); mainView.bringToFront(); mrightView.bringToFront(); mainView.bringToFront(); mScroller.startScroll(leftScrollX, 0, -leftWidth, 0, duration); postInvalidate(); } else if (leftScrollX == -leftWidth) { mScroller.startScroll(leftScrollX, 0, leftWidth, 0, duration); mainView.bringToFront(); postInvalidate(); } } } // 显示右边部分 public void showRight() { if (mrightView != null) { int leftScrollX = mainView.getScrollX(); if (leftScrollX == rightWidth) { mainView.bringToFront(); mScroller.startScroll(leftScrollX, 0, -rightWidth, 0, duration); postInvalidate(); } else if (leftScrollX == 0) { mainView_Content .setBackgroundResource(R.drawable.sliding_right); mainView.bringToFront(); mrightView.bringToFront(); mainView.bringToFront(); mScroller.startScroll(leftScrollX, 0, rightWidth, 0, duration); postInvalidate(); } else if (leftScrollX == -leftWidth) { mainView_Content .setBackgroundResource(R.drawable.sliding_right); mainView.bringToFront(); mrightView.bringToFront(); mainView.bringToFront(); // 这个条件可以不要,因为这种状态showleft 已经滑出去了 mScroller.startScroll(leftScrollX, 0, (leftWidth + rightWidth), 0, duration); postInvalidate(); } } } // 复位中间部分 public void resetCenter() { if (mainView != null) { mainView_Content.setBackgroundResource(R.drawable.ra_sliding_bg); mainView.bringToFront(); int x = mainView.getScrollX(); if (x > 0) { mScroller.startScroll(x, 0, -x, 0, duration); } else if (x < 0) { mScroller.startScroll(x, 0, -x, 0, duration); } else { mainView_Content .setBackgroundResource(R.drawable.ra_sliding_bg); lastMoveState = -1; } postInvalidate(); } } }