package com.partynetwork.iparty.ui.base; import android.content.Context; import android.util.AttributeSet; import android.util.TypedValue; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.Scroller; public class FlipperLayout extends ViewGroup { /** * 滑动 */ private Scroller mScroller; /** * 用于计算手指滑动的速度。 */ private VelocityTracker mVelocityTracker; /** * 左侧监听的滑动宽度 */ private int mWidth; /** * 监控范围 */ private static final int MONITORING_RANGE = 54; /** * 活动状态 */ private int mScreenState = 0; public static final int SCREEN_STATE_CLOSE = 0; public static final int SCREEN_STATE_OPEN = 1; /** * 触摸状态 */ private int mTouchState = 0; public static final int TOUCH_STATE_RESTART = 0; public static final int TOUCH_STATE_SCROLLING = 1; /** * 是否允许滑动 */ private int mScrollState = 0; public static final int SCROLL_STATE_NO_ALLOW = 0; public static final int SCROLL_STATE_ALLOW = 1; /* * 是否点击 */ private boolean mOnClick = false; public FlipperLayout(Context context) { super(context); mScroller = new Scroller(context); // 转换宽度为dip mWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, MONITORING_RANGE, getResources().getDisplayMetrics()); } public FlipperLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public FlipperLayout(Context context, AttributeSet attrs) { super(context, attrs); } protected void onLayout(boolean changed, int l, int t, int r, int b) { for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); int height = child.getMeasuredHeight(); int width = child.getMeasuredWidth(); child.layout(0, 0, width, height); } mScroller.startScroll(getChildAt(1).getScrollX(), 0, -getChildAt(1) .getScrollX() - (mWidth - getWidth()), 0, 1); invalidate(); } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); for (int i = 0; i < getChildCount(); i++) { getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec); } } /** * 这个方法用来分发TouchEvent * * * return true 分发给onTouchEvent处理 return false * 分发给onInterceptTouchEvent确定是否需要拦截 */ public boolean dispatchTouchEvent(MotionEvent ev) { obtainVelocityTracker(ev); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mTouchState = mScroller.isFinished() ? TOUCH_STATE_RESTART : TOUCH_STATE_SCROLLING; // 滑动结束才进入执行 if (mTouchState == TOUCH_STATE_RESTART) { int x = (int) ev.getX(); // 当滑动菜单关闭时,左边20个像素内可以触发滑动事件 当滑动菜单打开时,全屏监听 if (x <= 20 && mScreenState == SCREEN_STATE_CLOSE || mScreenState == SCREEN_STATE_OPEN) { if (mScreenState == SCREEN_STATE_OPEN) { mOnClick = true; } mScrollState = SCROLL_STATE_ALLOW; } else { mOnClick = false; mScrollState = SCROLL_STATE_NO_ALLOW; } } else { return false; } break; case MotionEvent.ACTION_MOVE: mVelocityTracker.computeCurrentVelocity(1000, ViewConfiguration.getMaximumFlingVelocity()); if (mScrollState == SCROLL_STATE_ALLOW && getWidth() - (int) ev.getX() < 0) { return true; } break; case MotionEvent.ACTION_UP: releaseVelocityTracker(); if (mOnClick) { mOnClick = false; mScreenState = SCREEN_STATE_CLOSE; mScroller.startScroll(getChildAt(1).getScrollX(), 0, -getChildAt(1).getScrollX(), 0, 800); invalidate(); } break; } return super.dispatchTouchEvent(ev); } /** * 这个方法用来拦截TouchEvent 是否拦截 如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 * onTouchEvent 来处理 如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 * dispatchTouchEvent 再来开始这个事件的分发。 */ public boolean onInterceptTouchEvent(MotionEvent ev) { obtainVelocityTracker(ev); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mTouchState = mScroller.isFinished() ? TOUCH_STATE_RESTART : TOUCH_STATE_SCROLLING; if (mTouchState == TOUCH_STATE_SCROLLING) { return false; } break; case MotionEvent.ACTION_MOVE: mVelocityTracker.computeCurrentVelocity(1000, ViewConfiguration.getMaximumFlingVelocity()); if (mScrollState == SCROLL_STATE_ALLOW && Math.abs(mVelocityTracker.getXVelocity()) > 200) { mOnClick = false; return true; } break; case MotionEvent.ACTION_UP: releaseVelocityTracker(); if (mScrollState == SCROLL_STATE_ALLOW && mScreenState == SCREEN_STATE_OPEN) { return true; } break; } return super.onInterceptTouchEvent(ev); } /** * 这个方法用来处理TouchEvent */ public boolean onTouchEvent(MotionEvent event) { obtainVelocityTracker(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mTouchState = mScroller.isFinished() ? TOUCH_STATE_RESTART : TOUCH_STATE_SCROLLING; if (mTouchState == TOUCH_STATE_SCROLLING) { return false; } break; case MotionEvent.ACTION_MOVE: mVelocityTracker.computeCurrentVelocity(1000, ViewConfiguration.getMaximumFlingVelocity()); getChildAt(1).scrollTo(-(int) event.getX() + getWidth() - 90, 0); break; case MotionEvent.ACTION_UP: if (mScrollState == SCROLL_STATE_ALLOW) { if (event.getX() < getWidth() / 2) { mScreenState = SCREEN_STATE_CLOSE; mScroller .startScroll(getChildAt(1).getScrollX(), 0, -getChildAt(1).getScrollX() - (mWidth - getWidth()), 0, 800); invalidate(); } else { mScreenState = SCREEN_STATE_OPEN; mScroller.startScroll(getChildAt(1).getScrollX(), 0, -getChildAt(1).getScrollX(), 0, 800); invalidate(); } } break; } return super.onTouchEvent(event); } public void open() { mTouchState = mScroller.isFinished() ? TOUCH_STATE_RESTART : TOUCH_STATE_SCROLLING; if (mTouchState == TOUCH_STATE_RESTART) { mScreenState = SCREEN_STATE_OPEN; mScroller.startScroll(getChildAt(1).getScrollX(), 0, -getChildAt(1) .getScrollX(), 0, 800); invalidate(); } } /** * 关闭并显示view * * @param view * 需要显示的view */ public void close(View view) { // 设置状态为关闭 mScreenState = SCREEN_STATE_CLOSE; // 设置滑动 mScroller.startScroll(getChildAt(1).getScrollX(), 0, -getChildAt(1) .getScrollX() - (mWidth - getWidth()), 0, 800); // 刷新 invalidate(); // 设置显示的控件 setContentView(view); } public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { getChildAt(1).scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } private void obtainVelocityTracker(MotionEvent event) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); } private void releaseVelocityTracker() { if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } } public int getScreenState() { return mScreenState; } public void setContentView(View view) { removeViewAt(0); addView(view, 0, getLayoutParams()); } public interface OnOpenListener { public abstract void open(); } public interface OnCloseListener { public abstract void close(); } }