Android侧滑效果简单实现代码

Android侧滑效果简单实现代码,第1张

概述先看看效果:首先,导入包:compilefiles(\'libs/nineoldandroids-2.4.0.jar\')r然后在main中创建一个widget包。

先看看效果:

首先,导入包:compile files('libs/nineoldandroIDs-2.4.0.jar')

r然后在main中创建一个Widget包。
c创建VIEwDragHelper类

public class VIEwDragHelper { private static final String TAG = "VIEwDragHelper"; public static final int INVALID_POINTER = -1 public static final int STATE_IDLE = 0; public static final int STATE_DRAGGING = 1; public static final int STATE_SETTliNG = 2; public static final int EDGE_left = 1 << 0; public static final int EDGE_RIGHT = 1 << 1 public static final int EDGE_top = 1 << 2; public static final int EDGE_BottOM = 1 << 3 public static final int EDGE_ALL = EDGE_left | EDGE_top | EDGE_RIGHT | EDGE_BottOM; public static final int DIRECTION_HORIZONTAL = 1 << 0; public static final int DIRECTION_VERTICAL = 1 << 1; public static final int DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL; private static final int EDGE_SIZE = 20; // dp private static final int BASE_SETTLE_DURATION = 256; // ms private static final int MAX_SETTLE_DURATION = 600; // ms // Current drag state; IDle,dragging or settling private int mDragState; // distance to travel before a drag may begin private int mtouchSlop; // Last kNown position/pointer tracking private int mActivePointerID = INVALID_POINTER; private float[] mInitialMotionX; private float[] mInitialMotionY; private float[] mLastMotionX; private float[] mLastMotionY; private int[] mInitialEdgestouched; private int[] mEdgeDragsInProgress; private int[] mEdgeDragsLocked; private int mPointersDown; private VeLocityTracker mVeLocityTracker; private final float mMaxVeLocity; private float mMinVeLocity; private final int mEdgeSize; private int mTrackingEdges; private final ScrollerCompat mScroller; private final Callback mCallback; private VIEw mCapturedVIEw; private boolean mReleaseInProgress; private final VIEwGroup mParentVIEw; private static final Interpolator sInterpolator = new Interpolator() {  public float getInterpolation(float t) {   t -= 1.0f;   return t * t * t * t * t + 1.0f;  } }; private final Runnable mSetIDleRunnable = new Runnable() {  public voID run() {   setDragState(STATE_IDLE);  } }; private VIEwDragHelper(Context context,VIEwGroup forParent,Callback cb) {  if (forParent == null) {   throw new IllegalArgumentException("Parent vIEw may not be null");  }  if (cb == null) {   throw new IllegalArgumentException("Callback may not be null");  }  mParentVIEw = forParent;  mCallback = cb;  final VIEwConfiguration vc = VIEwConfiguration.get(context);  final float density = context.getResources().getdisplayMetrics().density;  mEdgeSize = (int) (EDGE_SIZE * density + 0.5f);  mtouchSlop = vc.getScaledtouchSlop();  mMaxVeLocity = vc.getScaledMaximumFlingVeLocity();  mMinVeLocity = vc.getScaledMinimumFlingVeLocity();  mScroller = ScrollerCompat.create(context,sInterpolator); } public static abstract class Callback {  public voID onVIEwDragStateChanged(int state) {}  public voID onVIEwpositionChanged(VIEw changedVIEw,int left,int top,int dx,int dy) {}  public voID onVIEwCaptured(VIEw capturedChild,int activePointerID) {}  public voID onVIEwReleased(VIEw releasedChild,float xvel,float yvel) {}  public voID onEdgetouched(int edgeFlags,int pointerID) {}  public boolean onEdgeLock(int edgeFlags) {   return false;  }  public voID onEdgeDragStarted(int edgeFlags,int pointerID) {}  public int getorderedChildindex(int index) {   return index;  }  public int getVIEwHorizontalDragRange(VIEw child) {   return 0;  }  public int getVIEwVerticalDragRange(VIEw child) {   return 0;  }  public abstract boolean tryCaptureVIEw(VIEw child,int pointerID);  public int clampVIEwpositionHorizontal(VIEw child,int dx) {   return 0;  }  public int clampVIEwpositionVertical(VIEw child,int dy) {   return 0;  } } public static VIEwDragHelper create(VIEwGroup forParent,Callback cb) {  return new VIEwDragHelper(forParent.getContext(),forParent,cb); } public static VIEwDragHelper create(VIEwGroup forParent,float sensitivity,Callback cb) {  final VIEwDragHelper helper = create(forParent,cb);  helper.mtouchSlop = (int) (helper.mtouchSlop * (1 / sensitivity));  return helper; } public voID setMinVeLocity(float minVel) {  mMinVeLocity = minVel; } public float getMinVeLocity() {  return mMinVeLocity; } public int getVIEwDragState() {  return mDragState; } public voID setEdgeTrackingEnabled(int edgeFlags) {  mTrackingEdges = edgeFlags; } public int getEdgeSize() {  return mEdgeSize; } public voID captureChildVIEw(VIEw childVIEw,int activePointerID) {  if (childVIEw.getParent() != mParentVIEw) {   throw new IllegalArgumentException("captureChildVIEw: parameter must be a descendant " +     "of the VIEwDragHelper's tracked parent vIEw (" + mParentVIEw + ")");  }  mCapturedVIEw = childVIEw;  mActivePointerID = activePointerID;  mCallback.onVIEwCaptured(childVIEw,activePointerID);  setDragState(STATE_DRAGGING); } public VIEw getCapturedVIEw() {  return mCapturedVIEw; } public int getActivePointerID() {  return mActivePointerID; } public int gettouchSlop() {  return mtouchSlop; } public voID cancel() {  mActivePointerID = INVALID_POINTER;  clearMotionHistory();  if (mVeLocityTracker != null) {   mVeLocityTracker.recycle();   mVeLocityTracker = null;  } } public voID abort() {  cancel();  if (mDragState == STATE_SETTliNG) {   final int oldX = mScroller.getCurrX();   final int oldY = mScroller.getCurrY();   mScroller.abortAnimation();   final int newX = mScroller.getCurrX();   final int newY = mScroller.getCurrY();   mCallback.onVIEwpositionChanged(mCapturedVIEw,newX,newY,newX - oldX,newY - oldY);  }  setDragState(STATE_IDLE); } public boolean smoothSlIDeVIEwTo(VIEw child,int finalleft,int finaltop) {  mCapturedVIEw = child;  mActivePointerID = INVALID_POINTER;  boolean continueSlIDing = forceSettleCapturedVIEwAt(finalleft,finaltop,0);  if (!continueSlIDing && mDragState == STATE_IDLE && mCapturedVIEw != null) {   // If we're in an IDLE state to begin with and aren't moving anywhere,we   // end up having a non-null capturedVIEw with an IDLE dragState   mCapturedVIEw = null;  }  return continueSlIDing; } public boolean settleCapturedVIEwAt(int finalleft,int finaltop) {  if (!mReleaseInProgress) {   throw new IllegalStateException("Cannot settleCapturedVIEwAt outsIDe of a call to " +     "Callback#onVIEwReleased");  }  return forceSettleCapturedVIEwAt(finalleft,(int) VeLocityTrackerCompat.getXVeLocity(mVeLocityTracker,mActivePointerID),(int) VeLocityTrackerCompat.getYVeLocity(mVeLocityTracker,mActivePointerID)); } private boolean forceSettleCapturedVIEwAt(int finalleft,int finaltop,int xvel,int yvel) {  final int startleft = mCapturedVIEw.getleft();  final int starttop = mCapturedVIEw.gettop();  final int dx = finalleft - startleft;  final int dy = finaltop - starttop;  if (dx == 0 && dy == 0) {   // nothing to do. Send callbacks,be done.   mScroller.abortAnimation();   setDragState(STATE_IDLE);   return false;  }  final int duration = computeSettleDuration(mCapturedVIEw,dx,dy,xvel,yvel);  mScroller.startScroll(startleft,starttop,duration);  setDragState(STATE_SETTliNG);  return true; } private int computeSettleDuration(VIEw child,int dy,int yvel) {  xvel = clampMag(xvel,(int) mMinVeLocity,(int) mMaxVeLocity);  yvel = clampMag(yvel,(int) mMaxVeLocity);  final int absDx = Math.abs(dx);  final int absDy = Math.abs(dy);  final int absXVel = Math.abs(xvel);  final int absYVel = Math.abs(yvel);  final int addedVel = absXVel + absYVel;  final int addeddistance = absDx + absDy;  final float xweight = xvel != 0 ? (float) absXVel / addedVel :    (float) absDx / addeddistance;  final float yweight = yvel != 0 ? (float) absYVel / addedVel :    (float) absDy / addeddistance;  int xduration = computeAxisDuration(dx,mCallback.getVIEwHorizontalDragRange(child));  int yduration = computeAxisDuration(dy,yvel,mCallback.getVIEwVerticalDragRange(child));  return (int) (xduration * xweight + yduration * yweight); } private int computeAxisDuration(int delta,int veLocity,int motionRange) {  if (delta == 0) {   return 0;  }  final int wIDth = mParentVIEw.getWIDth();  final int halfWIDth = wIDth / 2;  final float distanceRatio = Math.min(1f,(float) Math.abs(delta) / wIDth);  final float distance = halfWIDth + halfWIDth *    distanceInfluenceForSnapDuration(distanceRatio);  int duration;  veLocity = Math.abs(veLocity);  if (veLocity > 0) {   duration = 4 * Math.round(1000 * Math.abs(distance / veLocity));  } else {   final float range = (float) Math.abs(delta) / motionRange;   duration = (int) ((range + 1) * BASE_SETTLE_DURATION);  }  return Math.min(duration,MAX_SETTLE_DURATION); } private static int clampMag(int value,int absMin,int absMax) {  final int absValue = Math.abs(value);  if (absValue < absMin) return 0;  if (absValue > absMax) return value > 0 ? absMax : -absMax;  return value; } private static float clampMag(float value,float absMin,float absMax) {  final float absValue = Math.abs(value);  if (absValue < absMin) return 0;  if (absValue > absMax) return value > 0 ? absMax : -absMax;  return value; } private static float distanceInfluenceForSnapDuration(float f) {  f -= 0.5f; // center the values about 0.  f *= 0.3f * Math.PI / 2.0f;  return (float) Math.sin(f); } public voID flingCapturedVIEw(int minleft,int mintop,int maxleft,int maxtop) {  if (!mReleaseInProgress) {   throw new IllegalStateException("Cannot flingCapturedVIEw outsIDe of a call to " +     "Callback#onVIEwReleased");  }  mScroller.fling(mCapturedVIEw.getleft(),mCapturedVIEw.gettop(),minleft,maxleft,mintop,maxtop);  setDragState(STATE_SETTliNG); } public boolean continueSettling(boolean deferCallbacks) {  if (mDragState == STATE_SETTliNG) {   boolean keepGoing = mScroller.computeScrollOffset();   final int x = mScroller.getCurrX();   final int y = mScroller.getCurrY();   final int dx = x - mCapturedVIEw.getleft();   final int dy = y - mCapturedVIEw.gettop();   if (dx != 0) {    mCapturedVIEw.offsetleftAndRight(dx);   }   if (dy != 0) {    mCapturedVIEw.offsettopAndBottom(dy);   }   if (dx != 0 || dy != 0) {    mCallback.onVIEwpositionChanged(mCapturedVIEw,x,y,dy);   }   if (keepGoing && x == mScroller.getFinalX() && y == mScroller.getFinalY()) {    // Close enough. The interpolator/scroller might think we're still moving    // but the user sure doesn't.    mScroller.abortAnimation();    keepGoing = false;   }   if (!keepGoing) {    if (deferCallbacks) {     mParentVIEw.post(mSetIDleRunnable);    } else {     setDragState(STATE_IDLE);    }   }  }  return mDragState == STATE_SETTliNG; } private voID dispatchVIEwReleased(float xvel,float yvel) {  mReleaseInProgress = true;  mCallback.onVIEwReleased(mCapturedVIEw,yvel);  mReleaseInProgress = false;  if (mDragState == STATE_DRAGGING) {   // onVIEwReleased dIDn't call a method that would have changed this. Go IDle.   setDragState(STATE_IDLE);  } } private voID clearMotionHistory() {  if (mInitialMotionX == null) {   return;  }  Arrays.fill(mInitialMotionX,0);  Arrays.fill(mInitialMotionY,0);  Arrays.fill(mLastMotionX,0);  Arrays.fill(mLastMotionY,0);  Arrays.fill(mInitialEdgestouched,0);  Arrays.fill(mEdgeDragsInProgress,0);  Arrays.fill(mEdgeDragsLocked,0);  mPointersDown = 0; } private voID clearMotionHistory(int pointerID) {  if (mInitialMotionX == null) {   return;  }  mInitialMotionX[pointerID] = 0;  mInitialMotionY[pointerID] = 0;  mLastMotionX[pointerID] = 0;  mLastMotionY[pointerID] = 0;  mInitialEdgestouched[pointerID] = 0;  mEdgeDragsInProgress[pointerID] = 0;  mEdgeDragsLocked[pointerID] = 0;  mPointersDown &= ~(1 << pointerID); } private voID ensureMotionHistorySizeforID(int pointerID) {  if (mInitialMotionX == null || mInitialMotionX.length <= pointerID) {   float[] imx = new float[pointerID + 1];   float[] imy = new float[pointerID + 1];   float[] lmx = new float[pointerID + 1];   float[] lmy = new float[pointerID + 1];   int[] iit = new int[pointerID + 1];   int[] edip = new int[pointerID + 1];   int[] edl = new int[pointerID + 1];   if (mInitialMotionX != null) {    System.arraycopy(mInitialMotionX,imx,mInitialMotionX.length);    System.arraycopy(mInitialMotionY,imy,mInitialMotionY.length);    System.arraycopy(mLastMotionX,lmx,mLastMotionX.length);    System.arraycopy(mLastMotionY,lmy,mLastMotionY.length);    System.arraycopy(mInitialEdgestouched,iit,mInitialEdgestouched.length);    System.arraycopy(mEdgeDragsInProgress,edip,mEdgeDragsInProgress.length);    System.arraycopy(mEdgeDragsLocked,edl,mEdgeDragsLocked.length);   }   mInitialMotionX = imx;   mInitialMotionY = imy;   mLastMotionX = lmx;   mLastMotionY = lmy;   mInitialEdgestouched = iit;   mEdgeDragsInProgress = edip;   mEdgeDragsLocked = edl;  } } private voID saveInitialMotion(float x,float y,int pointerID) {  ensureMotionHistorySizeforID(pointerID);  mInitialMotionX[pointerID] = mLastMotionX[pointerID] = x;  mInitialMotionY[pointerID] = mLastMotionY[pointerID] = y;  mInitialEdgestouched[pointerID] = getEdgestouched((int) x,(int) y);  mPointersDown |= 1 << pointerID; } private voID saveLastMotion(MotionEvent ev) {  final int pointerCount = MotionEventCompat.getPointerCount(ev);  for (int i = 0; i < pointerCount; i++) {   final int pointerID = MotionEventCompat.getPointerID(ev,i);   final float x = MotionEventCompat.getX(ev,i);   final float y = MotionEventCompat.getY(ev,i);   mLastMotionX[pointerID] = x;   mLastMotionY[pointerID] = y;  } } public boolean isPointerDown(int pointerID) {  return (mPointersDown & 1 << pointerID) != 0; } voID setDragState(int state) {  mParentVIEw.removeCallbacks(mSetIDleRunnable);  if (mDragState != state) {   mDragState = state;   mCallback.onVIEwDragStateChanged(state);   if (mDragState == STATE_IDLE) {    mCapturedVIEw = null;   }  } } boolean tryCaptureVIEwForDrag(VIEw toCapture,int pointerID) {  if (toCapture == mCapturedVIEw && mActivePointerID == pointerID) {   // Already done!   return true;  }  if (toCapture != null && mCallback.tryCaptureVIEw(toCapture,pointerID)) {   mActivePointerID = pointerID;   captureChildVIEw(toCapture,pointerID);   return true;  }  return false; } protected boolean canScroll(VIEw v,boolean checkV,int x,int y) {  if (v instanceof VIEwGroup) {   final VIEwGroup group = (VIEwGroup) v;   final int scrollX = v.getScrollX();   final int scrollY = v.getScrollY();   final int count = group.getChildCount();   // Count backwards - let topmost vIEws consume scroll distance first.   for (int i = count - 1; i >= 0; i--) {    // Todo: Add versioned support here for transformed vIEws.    // This will not work for transformed vIEws in Honeycomb+    final VIEw child = group.getChildAt(i);    if (x + scrollX >= child.getleft() && x + scrollX < child.getRight() &&      y + scrollY >= child.gettop() && y + scrollY < child.getBottom() &&      canScroll(child,true,x + scrollX - child.getleft(),y + scrollY - child.gettop())) {     return true;    }   }  }  return checkV && (VIEwCompat.canScrollHorizontally(v,-dx) ||    VIEwCompat.canScrollVertically(v,-dy)); } public boolean shouldIntercepttouchEvent(MotionEvent ev) {  final int action = MotionEventCompat.getActionMasked(ev);  final int actionIndex = MotionEventCompat.getActionIndex(ev);  if (action == MotionEvent.ACTION_DOWN) {   // reset things for a new event stream,just in case we dIDn't get   // the whole prevIoUs stream.   cancel();  }  if (mVeLocityTracker == null) {   mVeLocityTracker = VeLocityTracker.obtain();  }  mVeLocityTracker.addMovement(ev);  switch (action) {   case MotionEvent.ACTION_DOWN: {    final float x = ev.getX();    final float y = ev.getY();    final int pointerID = MotionEventCompat.getPointerID(ev,0);    saveInitialMotion(x,pointerID);    final VIEw toCapture = findtopChildUnder((int) x,(int) y);    // Catch a settling vIEw if possible.    if (toCapture == mCapturedVIEw && mDragState == STATE_SETTliNG) {     tryCaptureVIEwForDrag(toCapture,pointerID);    }    final int edgestouched = mInitialEdgestouched[pointerID];    if ((edgestouched & mTrackingEdges) != 0) {     mCallback.onEdgetouched(edgestouched & mTrackingEdges,pointerID);    }    break;   }   case MotionEventCompat.ACTION_POINTER_DOWN: {    final int pointerID = MotionEventCompat.getPointerID(ev,actionIndex);    final float x = MotionEventCompat.getX(ev,actionIndex);    final float y = MotionEventCompat.getY(ev,actionIndex);    saveInitialMotion(x,pointerID);    // A VIEwDragHelper can only manipulate one vIEw at a time.    if (mDragState == STATE_IDLE) {     final int edgestouched = mInitialEdgestouched[pointerID];     if ((edgestouched & mTrackingEdges) != 0) {      mCallback.onEdgetouched(edgestouched & mTrackingEdges,pointerID);     }    } else if (mDragState == STATE_SETTliNG) {     // Catch a settling vIEw if possible.     final VIEw toCapture = findtopChildUnder((int) x,(int) y);     if (toCapture == mCapturedVIEw) {      tryCaptureVIEwForDrag(toCapture,pointerID);     }    }    break;   }   case MotionEvent.ACTION_MOVE: {    if (mInitialMotionX == null || mInitialMotionY == null) break;    // First to cross a touch slop over a draggable vIEw wins. Also report edge drags.    final int pointerCount = MotionEventCompat.getPointerCount(ev);    for (int i = 0; i < pointerCount; i++) {     final int pointerID = MotionEventCompat.getPointerID(ev,i);     final float x = MotionEventCompat.getX(ev,i);     final float y = MotionEventCompat.getY(ev,i);     final float dx = x - mInitialMotionX[pointerID];     final float dy = y - mInitialMotionY[pointerID];     final VIEw toCapture = findtopChildUnder((int) x,(int) y);     final boolean pastSlop = toCapture != null && checktouchSlop(toCapture,dy);     if (pastSlop) {      // check the callback's      // getVIEw[Horizontal|Vertical]DragRange methods to kNow      // if you can move at all along an axis,then see if it      // would clamp to the same value. If you can't move at      // all in every dimension with a nonzero range,bail.      final int oldleft = toCapture.getleft();      final int targetleft = oldleft + (int) dx;      final int newleft = mCallback.clampVIEwpositionHorizontal(toCapture,targetleft,(int) dx);      final int oldtop = toCapture.gettop();      final int targettop = oldtop + (int) dy;      final int newtop = mCallback.clampVIEwpositionVertical(toCapture,targettop,(int) dy);      final int horizontalDragRange = mCallback.getVIEwHorizontalDragRange(        toCapture);      final int verticalDragRange = mCallback.getVIEwVerticalDragRange(toCapture);      if ((horizontalDragRange == 0 || horizontalDragRange > 0        && newleft == oldleft) && (verticalDragRange == 0        || verticalDragRange > 0 && newtop == oldtop)) {       break;      }     }     reportNewEdgeDrags(dx,pointerID);     if (mDragState == STATE_DRAGGING) {      // Callback might have started an edge drag      break;     }     if (pastSlop && tryCaptureVIEwForDrag(toCapture,pointerID)) {      break;     }    }    saveLastMotion(ev);    break;   }   case MotionEventCompat.ACTION_POINTER_UP: {    final int pointerID = MotionEventCompat.getPointerID(ev,actionIndex);    clearMotionHistory(pointerID);    break;   }   case MotionEvent.ACTION_UP:   case MotionEvent.ACTION_CANCEL: {    cancel();    break;   }   default:    break;  }  return mDragState == STATE_DRAGGING; } public voID processtouchEvent(MotionEvent ev) {  final int action = MotionEventCompat.getActionMasked(ev);  final int actionIndex = MotionEventCompat.getActionIndex(ev);  if (action == MotionEvent.ACTION_DOWN) {   // reset things for a new event stream,0);    final VIEw toCapture = findtopChildUnder((int) x,(int) y);    saveInitialMotion(x,pointerID);    // Since the parent is already directly processing this touch event,// there is no reason to delay for a slop before dragging.    // Start immediately if possible.    tryCaptureVIEwForDrag(toCapture,pointerID);    final int edgestouched = mInitialEdgestouched[pointerID];    if ((edgestouched & mTrackingEdges) != 0) {     mCallback.onEdgetouched(edgestouched & mTrackingEdges,pointerID);    // A VIEwDragHelper can only manipulate one vIEw at a time.    if (mDragState == STATE_IDLE) {     // If we're IDle we can do anything! Treat it like a normal down event.     final VIEw toCapture = findtopChildUnder((int) x,(int) y);     tryCaptureVIEwForDrag(toCapture,pointerID);     final int edgestouched = mInitialEdgestouched[pointerID];     if ((edgestouched & mTrackingEdges) != 0) {      mCallback.onEdgetouched(edgestouched & mTrackingEdges,pointerID);     }    } else if (isCapturedVIEwUnder((int) x,(int) y)) {     // We're still tracking a captured vIEw. If the same vIEw is under this     // point,we'll swap to controlling it with this pointer instead.     // (This will still work if we're "catching" a settling vIEw.)     tryCaptureVIEwForDrag(mCapturedVIEw,pointerID);    }    break;   }   case MotionEvent.ACTION_MOVE: {    if (mDragState == STATE_DRAGGING) {     final int index = MotionEventCompat.findPointerIndex(ev,mActivePointerID);     final float x = MotionEventCompat.getX(ev,index);     final float y = MotionEventCompat.getY(ev,index);     final int IDx = (int) (x - mLastMotionX[mActivePointerID]);     final int IDy = (int) (y - mLastMotionY[mActivePointerID]);     dragTo(mCapturedVIEw.getleft() + IDx,mCapturedVIEw.gettop() + IDy,IDx,IDy);     saveLastMotion(ev);    } else {     // Check to see if any pointer is Now over a draggable vIEw.     final int pointerCount = MotionEventCompat.getPointerCount(ev);     for (int i = 0; i < pointerCount; i++) {      final int pointerID = MotionEventCompat.getPointerID(ev,i);      final float x = MotionEventCompat.getX(ev,i);      final float y = MotionEventCompat.getY(ev,i);      final float dx = x - mInitialMotionX[pointerID];      final float dy = y - mInitialMotionY[pointerID];      reportNewEdgeDrags(dx,pointerID);      if (mDragState == STATE_DRAGGING) {       // Callback might have started an edge drag.       break;      }      final VIEw toCapture = findtopChildUnder((int) x,(int) y);      if (checktouchSlop(toCapture,dy) &&        tryCaptureVIEwForDrag(toCapture,pointerID)) {       break;      }     }     saveLastMotion(ev);    }    break;   }   case MotionEventCompat.ACTION_POINTER_UP: {    final int pointerID = MotionEventCompat.getPointerID(ev,actionIndex);    if (mDragState == STATE_DRAGGING && pointerID == mActivePointerID) {     // Try to find another pointer that's still holding on to the captured vIEw.     int newActivePointer = INVALID_POINTER;     final int pointerCount = MotionEventCompat.getPointerCount(ev);     for (int i = 0; i < pointerCount; i++) {      final int ID = MotionEventCompat.getPointerID(ev,i);      if (ID == mActivePointerID) {       // This one's going away,skip.       continue;      }      final float x = MotionEventCompat.getX(ev,i);      if (findtopChildUnder((int) x,(int) y) == mCapturedVIEw &&        tryCaptureVIEwForDrag(mCapturedVIEw,ID)) {       newActivePointer = mActivePointerID;       break;      }     }     if (newActivePointer == INVALID_POINTER) {      // We dIDn't find another pointer still touching the vIEw,release it.      releaseVIEwForPointerUp();     }    }    clearMotionHistory(pointerID);    break;   }   case MotionEvent.ACTION_UP: {    if (mDragState == STATE_DRAGGING) {     releaseVIEwForPointerUp();    }    cancel();    break;   }   case MotionEvent.ACTION_CANCEL: {    if (mDragState == STATE_DRAGGING) {     dispatchVIEwReleased(0,0);    }    cancel();    break;   }   default:    break;  } } private voID reportNewEdgeDrags(float dx,float dy,int pointerID) {  int dragsstarted = 0;  if (checkNewEdgeDrag(dx,pointerID,EDGE_left)) {   dragsstarted |= EDGE_left;  }  if (checkNewEdgeDrag(dy,EDGE_top)) {   dragsstarted |= EDGE_top;  }  if (checkNewEdgeDrag(dx,EDGE_RIGHT)) {   dragsstarted |= EDGE_RIGHT;  }  if (checkNewEdgeDrag(dy,EDGE_BottOM)) {   dragsstarted |= EDGE_BottOM;  }  if (dragsstarted != 0) {   mEdgeDragsInProgress[pointerID] |= dragsstarted;   mCallback.onEdgeDragStarted(dragsstarted,pointerID);  } } private boolean checkNewEdgeDrag(float delta,float odelta,int pointerID,int edge) {  final float absDelta = Math.abs(delta);  final float absODelta = Math.abs(odelta);  if ((mInitialEdgestouched[pointerID] & edge) != edge || (mTrackingEdges & edge) == 0 ||    (mEdgeDragsLocked[pointerID] & edge) == edge ||    (mEdgeDragsInProgress[pointerID] & edge) == edge ||    (absDelta <= mtouchSlop && absODelta <= mtouchSlop)) {   return false;  }  if (absDelta < absODelta * 0.5f && mCallback.onEdgeLock(edge)) {   mEdgeDragsLocked[pointerID] |= edge;   return false;  }  return (mEdgeDragsInProgress[pointerID] & edge) == 0 && absDelta > mtouchSlop; } private boolean checktouchSlop(VIEw child,float dx,float dy) {  if (child == null) {   return false;  }  final boolean checkHorizontal = mCallback.getVIEwHorizontalDragRange(child) > 0;  final boolean checkVertical = mCallback.getVIEwVerticalDragRange(child) > 0;  if (checkHorizontal && checkVertical) {   return dx * dx + dy * dy > mtouchSlop * mtouchSlop;  } else if (checkHorizontal) {   return Math.abs(dx) > mtouchSlop;  } else if (checkVertical) {   return Math.abs(dy) > mtouchSlop;  }  return false; } public boolean checktouchSlop(int directions) {  final int count = mInitialMotionX.length;  for (int i = 0; i < count; i++) {   if (checktouchSlop(directions,i)) {    return true;   }  }  return false; } public boolean checktouchSlop(int directions,int pointerID) {  if (!isPointerDown(pointerID)) {   return false;  }  final boolean checkHorizontal = (directions & DIRECTION_HORIZONTAL) == DIRECTION_HORIZONTAL;  final boolean checkVertical = (directions & DIRECTION_VERTICAL) == DIRECTION_VERTICAL;  final float dx = mLastMotionX[pointerID] - mInitialMotionX[pointerID];  final float dy = mLastMotionY[pointerID] - mInitialMotionY[pointerID];  if (checkHorizontal && checkVertical) {   return dx * dx + dy * dy > mtouchSlop * mtouchSlop;  } else if (checkHorizontal) {   return Math.abs(dx) > mtouchSlop;  } else if (checkVertical) {   return Math.abs(dy) > mtouchSlop;  }  return false; } public boolean isEdgetouched(int edges) {  final int count = mInitialEdgestouched.length;  for (int i = 0; i < count; i++) {   if (isEdgetouched(edges,i)) {    return true;   }  }  return false; } public boolean isEdgetouched(int edges,int pointerID) {  return isPointerDown(pointerID) && (mInitialEdgestouched[pointerID] & edges) != 0; } private voID releaseVIEwForPointerUp() {  mVeLocityTracker.computeCurrentVeLocity(1000,mMaxVeLocity);  final float xvel = clampMag(    VeLocityTrackerCompat.getXVeLocity(mVeLocityTracker,mMinVeLocity,mMaxVeLocity);  final float yvel = clampMag(    VeLocityTrackerCompat.getYVeLocity(mVeLocityTracker,mMaxVeLocity);  dispatchVIEwReleased(xvel,yvel); } private voID dragTo(int left,int dy) {  int clampedX = left;  int clampedY = top;  final int oldleft = mCapturedVIEw.getleft();  final int oldtop = mCapturedVIEw.gettop();  if (dx != 0) {   clampedX = mCallback.clampVIEwpositionHorizontal(mCapturedVIEw,left,dx);   mCapturedVIEw.offsetleftAndRight(clampedX - oldleft);  }  if (dy != 0) {   clampedY = mCallback.clampVIEwpositionVertical(mCapturedVIEw,top,dy);   mCapturedVIEw.offsettopAndBottom(clampedY - oldtop);  }  if (dx != 0 || dy != 0) {   final int clampedDx = clampedX - oldleft;   final int clampedDy = clampedY - oldtop;   mCallback.onVIEwpositionChanged(mCapturedVIEw,clampedX,clampedY,clampedDx,clampedDy);  } } public boolean isCapturedVIEwUnder(int x,int y) {  return isVIEwUnder(mCapturedVIEw,y); } public boolean isVIEwUnder(VIEw vIEw,int y) {  if (vIEw == null) {   return false;  }  return x >= vIEw.getleft() &&    x < vIEw.getRight() &&    y >= vIEw.gettop() &&    y < vIEw.getBottom(); } public VIEw findtopChildUnder(int x,int y) {  final int childCount = mParentVIEw.getChildCount();  for (int i = childCount - 1; i >= 0; i--) {   final VIEw child = mParentVIEw.getChildAt(mCallback.getorderedChildindex(i));   if (x >= child.getleft() && x < child.getRight() &&     y >= child.gettop() && y < child.getBottom()) {    return child;   }  }  return null; } private int getEdgestouched(int x,int y) {  int result = 0;  if (x < mParentVIEw.getleft() + mEdgeSize) result |= EDGE_left;  if (y < mParentVIEw.gettop() + mEdgeSize) result |= EDGE_top;  if (x > mParentVIEw.getRight() - mEdgeSize) result |= EDGE_RIGHT;  if (y > mParentVIEw.getBottom() - mEdgeSize) result |= EDGE_BottOM;  return result; }}

DragLayout布局继承FrameLayout:

public class DragLayout extends FrameLayout { private static final boolean IS_SHOW_SHADOW = true; //手势处理类 private GestureDetectorCompat gestureDetector; //视图拖拽移动帮助类 private VIEwDragHelper dragHelper; //滑动监听器 private DragListener dragListener; //水平拖拽的距离 private int range; //宽度 private int wIDth; //高度 private int height; //main视图距离在VIEwGroup距离左边的距离 private int mainleft; private Context context; private ImageVIEw ivShadow; //左侧布局 private relativeLayout vgleft; //右侧(主界面布局) private CustomrelativeLayout vgMain; //页面状态 默认为关闭 private Status status = Status.CLOSE; private final VIEwDragHelper.Callback dragHelperCallback = new VIEwDragHelper.Callback() {  @OverrIDe  public int clampVIEwpositionHorizontal(VIEw child,int dx) {   if (mainleft + dx < 0) {    return 0;   } else if (mainleft + dx > range) {    return range;   } else {    return left;   }  }  @OverrIDe  public boolean tryCaptureVIEw(VIEw child,int pointerID) {   return true;  }  @OverrIDe  public int getVIEwHorizontalDragRange(VIEw child) {   return wIDth;  }  @OverrIDe  public voID onVIEwReleased(VIEw releasedChild,float yvel) {   super.onVIEwReleased(releasedChild,yvel);   if (xvel > 0) {    open();   } else if (xvel < 0) {    close();   } else if (releasedChild == vgMain && mainleft > range * 0.3) {    open();   } else if (releasedChild == vgleft && mainleft > range * 0.7) {    open();   } else {    close();   }  }  @OverrIDe  public voID onVIEwpositionChanged(VIEw changedVIEw,int dy) {   if (changedVIEw == vgMain) {    mainleft = left;   } else {    mainleft = mainleft + left;   }   if (mainleft < 0) {    mainleft = 0;   } else if (mainleft > range) {    mainleft = range;   }   if (IS_SHOW_SHADOW) {    ivShadow.layout(mainleft,mainleft + wIDth,height);   }   if (changedVIEw == vgleft) {    vgleft.layout(0,wIDth,height);    vgMain.layout(mainleft,height);   }   dispatchDragEvent(mainleft);  } }; public DragLayout(Context context) {  this(context,null); } public DragLayout(Context context,AttributeSet attrs) {  this(context,attrs,0);  this.context = context; } public DragLayout(Context context,AttributeSet attrs,int defStyle) {  super(context,defStyle);  gestureDetector = new GestureDetectorCompat(context,new YScrollDetector());  dragHelper = VIEwDragHelper.create(this,dragHelperCallback); } class YScrollDetector extends GestureDetector.SimpleOnGestureListener {  @OverrIDe  public boolean onScroll(MotionEvent e1,MotionEvent e2,float dy) {   return Math.abs(dy) <= Math.abs(dx);  } } /**  * 滑动相关回调接口  */ public interface DragListener {  //界面打开  public voID onopen();  //界面关闭  public voID onClose();  //界面滑动过程中  public voID onDrag(float percent); } public voID setDragListener(DragListener dragListener) {  this.dragListener = dragListener; } /**  * 布局加载完成回调  * 做一些初始化的 *** 作  */ @OverrIDe protected voID onFinishInflate() {  super.onFinishInflate();  if (IS_SHOW_SHADOW) {   ivShadow = new ImageVIEw(context);   ivShadow.setimageResource(R.mipmap.shadow);   LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);   addVIEw(ivShadow,1,lp);  }  //左侧界面  vgleft = (relativeLayout) getChildAt(0);  //右侧(主)界面  vgMain = (CustomrelativeLayout) getChildAt(IS_SHOW_SHADOW ? 2 : 1);  vgMain.setDragLayout(this);  vgleft.setClickable(true);  vgMain.setClickable(true); } public VIEwGroup getVgMain() {  return vgMain; } public VIEwGroup getVgleft() {  return vgleft; } @OverrIDe protected voID onSizeChanged(int w,int h,int olDW,int oldh) {  super.onSizeChanged(w,h,olDW,oldh);  wIDth = vgleft.getMeasureDWIDth();  height = vgleft.getMeasuredHeight();  //可以水平拖拽滑动的距离 一共为屏幕宽度的80%  range = (int) (wIDth * 0.8f); } @OverrIDe protected voID onLayout(boolean changed,int right,int bottom) {  vgleft.layout(0,height);  vgMain.layout(mainleft,height); } /**  * 拦截触摸事件  * @param ev  * @return  */ @OverrIDe public boolean onIntercepttouchEvent(MotionEvent ev) {  return dragHelper.shouldIntercepttouchEvent(ev) && gestureDetector.ontouchEvent(ev); } /**  * 将拦截的到事件给VIEwDragHelper进行处理  * @param e  * @return  */ @OverrIDe public boolean ontouchEvent(MotionEvent e) {  try {   dragHelper.processtouchEvent(e);  } catch (Exception ex) {   ex.printstacktrace();  }  return false; } /**  * 进行处理拖拽事件  * @param mainleft  */ private voID dispatchDragEvent(int mainleft) {  if (dragListener == null) {   return;  }  float percent = mainleft / (float) range;  //滑动动画效果  animateVIEw(percent);  //进行回调滑动的百分比  dragListener.onDrag(percent);  Status lastStatus = status;  if (lastStatus != getStatus() && status == Status.CLOSE) {   dragListener.onClose();  } else if (lastStatus != getStatus() && status == Status.OPEN) {   dragListener.onopen();  } } /**  * 根据滑动的距离的比例,进行平移动画  * @param percent  */ private voID animateVIEw(float percent) {  float f1 = 1 - percent * 0.5f;  VIEwHelper.setTranslationX(vgleft,-vgleft.getWIDth() / 2.5f + vgleft.getWIDth() / 2.5f * percent);  if (IS_SHOW_SHADOW) {   //阴影效果视图大小进行缩放   VIEwHelper.setScaleX(ivShadow,f1 * 1.2f * (1 - percent * 0.10f));   VIEwHelper.setScaleY(ivShadow,f1 * 1.85f * (1 - percent * 0.10f));  } } /**  * 有加速度,当我们停止滑动的时候,该不会立即停止动画效果  */ @OverrIDe public voID computeScroll() {  if (dragHelper.continueSettling(true)) {   VIEwCompat.postInvalIDateOnAnimation(this);  } } /**  * 页面状态(滑动,打开,关闭)  */ public enum Status {  DRAG,OPEN,CLOSE } /**  * 页面状态设置  * @return  */ public Status getStatus() {  if (mainleft == 0) {   status = Status.CLOSE;  } else if (mainleft == range) {   status = Status.OPEN;  } else {   status = Status.DRAG;  }  return status; } public voID open() {  open(true); } public voID open(boolean animate) {  if (animate) {   //继续滑动   if (dragHelper.smoothSlIDeVIEwTo(vgMain,range,0)) {    VIEwCompat.postInvalIDateOnAnimation(this);   }  } else {   vgMain.layout(range,range * 2,height);   dispatchDragEvent(range);  } } public voID close() {  close(true); } public voID close(boolean animate) {  if (animate) {   //继续滑动   if (dragHelper.smoothSlIDeVIEwTo(vgMain,0)) {    VIEwCompat.postInvalIDateOnAnimation(this);   }  } else {   vgMain.layout(0,height);   dispatchDragEvent(0);  } }}

CustomrelativeLayout:

public class CustomrelativeLayout extends relativeLayout { private DragLayout dl; public CustomrelativeLayout(Context context) {  super(context); } public CustomrelativeLayout(Context context,AttributeSet attrs) {  super(context,attrs); } public CustomrelativeLayout(Context context,int defStyleAttr) {  super(context,defStyleAttr); } public voID setDragLayout(DragLayout dl) {  this.dl = dl; } @OverrIDe public boolean onIntercepttouchEvent(MotionEvent event) {  if (dl.getStatus() != DragLayout.Status.CLOSE) {   return true;  }  return super.onIntercepttouchEvent(event); } @OverrIDe public boolean ontouchEvent(MotionEvent event) {  if (dl.getStatus() != DragLayout.Status.CLOSE) {   if (event.getAction() == MotionEvent.ACTION_UP) {    dl.close();   }   return true;  }  return super.ontouchEvent(event); }}

c沉浸式状态栏:BaseActivity:

public class BaseActivity extends FragmentActivity { @OverrIDe protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  this.requestwindowFeature(Window.FEATURE_NO_Title);  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {   //透明状态栏   getwindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);   //透明导航栏   getwindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);  } } /**  * 设置沉浸式状态栏  */ protected voID setStatusbar() {  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {   final VIEwGroup linear_bar = (VIEwGroup) findVIEwByID(R.ID.rl_Title);   final int statusHeight = getStatusbarHeight();   linear_bar.post(new Runnable() {    @OverrIDe    public voID run() {     int TitleHeight = linear_bar.getHeight();     androID.Widget.linearLayout.LayoutParams params = (androID.Widget.linearLayout.LayoutParams) linear_bar.getLayoutParams();     params.height = statusHeight + TitleHeight;     linear_bar.setLayoutParams(params);    }   });  } } /**  * 获取状态栏的高度  * @return  */ protected int getStatusbarHeight(){  try  {   Class<?> c=Class.forname("com.androID.internal.R$dimen");   Object obj=c.newInstance();   FIEld fIEld=c.getFIEld("status_bar_height");   int x=Integer.parseInt(fIEld.get(obj).toString());   return getResources().getDimensionPixelSize(x);  }catch(Exception e){   e.printstacktrace();  }  return 0; }}

MainActivity:

public class MainActivity extends BaseActivity { private DragLayout dl; private linearLayout linearLayout; @OverrIDe protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentVIEw(R.layout.activity_main);  initDragLayout(); } private voID initDragLayout() {  dl = (DragLayout) findVIEwByID(R.ID.dl);  linearLayout =(linearLayout) findVIEwByID(R.ID.aaa);  dl.setDragListener(new DragLayout.DragListener() {   //界面打开的时候   @OverrIDe   public voID onopen() {   }   //界面关闭的时候   @OverrIDe   public voID onClose() {   }   //界面滑动的时候   @OverrIDe   public voID onDrag(float percent) {   }  }); }}

OneFragment:

public class OneFragment extends Fragment { private VIEw mVIEw; @OverrIDe public VIEw onCreateVIEw(LayoutInflater inflater,VIEwGroup container,Bundle savedInstanceState) {  if(mVIEw==null){   mVIEw=inflater.inflate(R.layout.one_frag_layout,container,false);  }  return mVIEw; }}

b布局文件:
one_frag_layout.xml
linearLayout布局

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:gravity="center" androID:ID="@+ID/aaa" > <TextVIEw  androID:text="界面"  androID:layout_gravity="center"  androID:layout_wIDth="wrap_content"  androID:layout_height="wrap_content" /></linearLayout>

one_frag_layout1.xml:
relativeLayout布局

<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:gravity="center" > <TextVIEw  androID:text="主界面"  androID:layout_gravity="center"  androID:layout_wIDth="wrap_content"  androID:layout_height="wrap_content" /></relativeLayout>

activity.main.xml:

<com.包名.myapplication.Widget.DragLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:ID="@+ID/dl" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@androID:color/transparent" > <!--下层 左边的布局 这个布局不能省去--> <include layout="@layout/one_frag_layout1"/> <!--上层 右边的主布局--> <com.包名.myapplication.Widget.CustomrelativeLayout  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent"  androID:background="#FFFFFF"  >  <linearLayout   androID:layout_wIDth="fill_parent"   androID:layout_height="fill_parent"   androID:orIEntation="vertical"   >  <relativeLayout   androID:ID="@+ID/rl_Title"   androID:layout_wIDth="match_parent"   androID:layout_height="49dp"   androID:gravity="bottom"   androID:background="#2aaced"    >   <include layout="@layout/one_frag_layout"/>  </relativeLayout>  <!--中间内容后面放入Fragment-->  <FrameLayout   androID:layout_wIDth="fill_parent"   androID:layout_height="fill_parent"   >   <fragment    androID:ID="@+ID/main_info_fragment"        androID:layout_wIDth="fill_parent"    androID:layout_height="fill_parent"/>  </FrameLayout>  </linearLayout> </com.包名.myapplication.Widget.CustomrelativeLayout></com.包名.myapplication.Widget.DragLayout>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android侧滑效果简单实现代码全部内容,希望文章能够帮你解决Android侧滑效果简单实现代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147628.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存