/** * 自定义可以滑动的RelativeLayout, 类似于IOS的滑动删除页面效果,当我们要使用 * 此功能的时候,需要将该Activity的顶层布局设置为SildingFinishLayout, * 然后需要调用setTouchView()方法来设置需要滑动的View * * @author xiaanming * * @bloghttp://blog.csdn.net/xiaanming * */ publicclassSildingFinishLayout extendsRelativeLayout implements OnTouchListener { /** * SildingFinishLayout布局的父布局 */ privateViewGroup mParentView; /** * 处理滑动逻辑的View */ privateView touchView; /** * 滑动的最小距离 */ privateint mTouchSlop; /** * 按下点的X坐标 */ privateint downX; /** * 按下点的Y坐标 */ privateint downY; /** * 临时存储X坐标 */ privateint tempX; /** * 滑动类 */ privateScroller mScroller; /** * SildingFinishLayout的宽度 */ privateint viewWidth; /** * 记录是否正在滑动 */ private boolean isSilding; privateOnSildingFinishListener onSildingFinishListener; private boolean isFinish; publicSildingFinishLayout(Context context,AttributeSet attrs) { this(context, attrs,0); } publicSildingFinishLayout(Context context,AttributeSet attrs,int defStyle) { super(context, attrs, defStyle); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mScroller = new Scroller(context); } @Override protectedvoidonLayout(boolean changed,int l,int t,int r,int b) { super.onLayout(changed, l, t, r, b); if (changed) { // 获取SildingFinishLayout所在布局的父布局 mParentView = (ViewGroup)this.getParent(); viewWidth = this.getWidth(); } } /** * 设置OnSildingFinishListener, 在onSildingFinish()方法中finish Activity * * @param onSildingFinishListener */ publicvoidsetOnSildingFinishListener( OnSildingFinishListener onSildingFinishListener) { this.onSildingFinishListener= onSildingFinishListener; } /** * 设置Touch的View * * @param touchView */ publicvoidsetTouchView(View touchView) { this.touchView= touchView; touchView.setOnTouchListener(this); } publicViewgetTouchView() { return touchView; } /** * 滚动出界面 */ privatevoidscrollRight() { final int delta = (viewWidth+ mParentView.getScrollX()); // 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item mScroller.startScroll(mParentView.getScrollX(),0,-delta + 1, 0, Math.abs(delta)); postInvalidate(); } /** * 滚动到起始位置 */ privatevoidscrollOrigin() { int delta= mParentView.getScrollX(); mScroller.startScroll(mParentView.getScrollX(),0,-delta, 0, Math.abs(delta)); postInvalidate(); } /** * touch的View是否是AbsListView, 例如ListView, GridView等其子类 * * @return */ private booleanisTouchOnAbsListView() { return touchView instanceofAbsListView? true : false; } /** * touch的view是否是ScrollView或者其子类 * * @return */ private booleanisTouchOnScrollView() { return touchView instanceofScrollView? true : false; } @Override public booleanonTouch(View v,MotionEventevent) { switch (event.getAction()) { caseMotionEvent.ACTION_DOWN: downX = tempX = (int)event.getRawX(); downY = (int)event.getRawY(); break; caseMotionEvent.ACTION_MOVE: int moveX= (int)event.getRawX(); int deltaX= tempX - moveX; tempX = moveX; if (Math.abs(moveX- downX) > mTouchSlop &&Math.abs((int)event.getRawY()- downY) < mTouchSlop) { isSilding = true; // 若touchView是AbsListView, // 则当手指滑动,取消item的点击事件,不然我们滑动也伴随着item点击事件的发生 if (isTouchOnAbsListView()) { MotionEvent cancelEvent= MotionEvent.obtain(event); cancelEvent .setAction(MotionEvent.ACTION_CANCEL | (event.getActionIndex()<< MotionEvent.ACTION_POINTER_INDEX_SHIFT)); v.onTouchEvent(cancelEvent); } } if (moveX- downX >= 0 && isSilding) { mParentView.scrollBy(deltaX,0); // 屏蔽在滑动过程中ListView ScrollView等自己的滑动事件 if (isTouchOnScrollView()||isTouchOnAbsListView()) { returntrue; } } break; caseMotionEvent.ACTION_UP: isSilding = false; if (mParentView.getScrollX()<=-viewWidth / 2) { isFinish = true; scrollRight(); } else { scrollOrigin(); isFinish = false; } break; } // 假如touch的view是AbsListView或者ScrollView 我们处理完上面自己的逻辑之后 // 再交给AbsListView, ScrollView自己处理其自己的逻辑 if (isTouchOnScrollView()||isTouchOnAbsListView()) { return v.onTouchEvent(event); } // 其他的情况直接返回true returntrue; } @Override publicvoidcomputeScroll() { // 调用startScroll的时候scroller.computeScrollOffset()返回true, if (mScroller.computeScrollOffset()) { mParentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); if (mScroller.isFinished()) { if (onSildingFinishListener!=null&& isFinish) { onSildingFinishListener.onSildingFinish(); } } } } publicinterfaceOnSildingFinishListener { publicvoidonSildingFinish(); } }