iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android侧滑效果简单实现代码
  • 847
分享到

Android侧滑效果简单实现代码

Android 2022-06-06 05:06:15 847人浏览 八月长安
摘要

先看看效果: 首先,导入包:compile files('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 left, int dx) {
   return 0;
  }
  public int clampViewPositionVertical(View child, int top, 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, 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, finalTop,
    (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, dx, dy, duration);
  setDragState(STATE_SETTLING);
  return true;
 }
 private int computeSettleDuration(View child, int dx, int dy, int xvel, int yvel) {
  xvel = clampMag(xvel, (int) mMinVelocity, (int) mMaxVelocity);
  yvel = clampMag(yvel, (int) mMinVelocity, (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, xvel, 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(),
    (int) VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId),
    (int) VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId),
    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, dx, 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, xvel, 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, 0, imx, 0, mInitialMotionX.length);
    System.arraycopy(mInitialMotionY, 0, imy, 0, mInitialMotionY.length);
    System.arraycopy(mLastMotionX, 0, lmx, 0, mLastMotionX.length);
    System.arraycopy(mLastMotionY, 0, lmy, 0, mLastMotionY.length);
    System.arraycopy(mInitialEdgesTouched, 0, iit, 0, mInitialEdgesTouched.length);
    System.arraycopy(mEdgeDragsInProgress, 0, edip, 0, mEdgeDragsInProgress.length);
    System.arraycopy(mEdgeDragsLocked, 0, edl, 0, 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 dx, int dy, 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, dx, dy, 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, y, 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, y, 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, dx, 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, dy, 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, 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);
    final View toCapture = findTopChildUnder((int) x, (int) y);
    saveInitialMotion(x, y, 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);
    }
    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, y, 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, dy, pointerId);
      if (mDragState == STATE_DRAGGING) {
       // Callback might have started an edge drag.
       break;
      }
      final View toCapture = findTopChildUnder((int) x, (int) y);
      if (checkTouchSlop(toCapture, dx, 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);
      final float y = MotionEventCompat.getY(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, dy, pointerId, EDGE_LEFT)) {
   dragsStarted |= EDGE_LEFT;
  }
  if (checkNewEdgeDrag(dy, dx, pointerId, EDGE_TOP)) {
   dragsStarted |= EDGE_TOP;
  }
  if (checkNewEdgeDrag(dx, dy, pointerId, EDGE_RIGHT)) {
   dragsStarted |= EDGE_RIGHT;
  }
  if (checkNewEdgeDrag(dy, dx, pointerId, 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, mActivePointerId),
    mMinVelocity, mMaxVelocity);
  final float yvel = clampMag(
    VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId),
    mMinVelocity, mMaxVelocity);
  dispatchViewReleased(xvel, yvel);
 }
 private void dragTo(int left, int top, int dx, 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, x, y);
 }
 public boolean isViewUnder(View view, int x, 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 left, 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 xvel, float yvel) {
   super.onViewReleased(releasedChild, xvel, 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 left, int top,
           int dx, 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, 0, mainLeft + width, height);
   }
   if (changedView == vgLeft) {
    vgLeft.layout(0, 0, width, height);
    vgMain.layout(mainLeft, 0, mainLeft + width, 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, attrs, 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 dx, 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 left, int top, int right, int bottom) {
  vgLeft.layout(0, 0, width, height);
  vgMain.layout(mainLeft, 0, mainLeft + width, height);
 }
 
 @Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  return dragHelper.shouldInterceptTouchEvent(ev) && gestureDetector.onTouchEvent(ev);
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent e) {
  try {
   dragHelper.processTouchEvent(e);
  } catch (Exception ex) {
   ex.printStackTrace();
  }
  return false;
 }
 
 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();
  }
 }
 
 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
 }
 
 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, 0, range * 2, height);
   dispatchDragEvent(range);
  }
 }
 public void close() {
  close(true);
 }
 public void close(boolean animate) {
  if (animate) {
   //继续滑动
   if (dragHelper.smoothSlideViewTo(vgMain, 0, 0)) {
    ViewCompat.postInvalidateOnAnimation(this);
   }
  } else {
   vgMain.layout(0, 0, width, 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, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, 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);
    }
   });
  }
 }
 
 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"
    class="com.mieasy.myapplication.OneFragment"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>
  </FrameLayout>
  </LinearLayout>
 </com.包名.myapplication.widget.CustomRelativeLayout>
</com.包名.myapplication.widget.DragLayout>
您可能感兴趣的文章:Android实现网易新闻客户端侧滑菜单(2)Android DrawerLayout带有侧滑功能的布局类(1)Android基于ViewDragHelper仿QQ5.0侧滑界面效果Android自定义可编辑、删除的侧滑LisitViewAndroid自定义控件简单实现侧滑菜单效果Android高仿QQ6.0侧滑删除实例代码Android使用ViewDragHelper实现仿QQ6.0侧滑界面(一)Android使用ViewDragHelper实现QQ6.X最新版本侧滑界面效果实例代码Android滑动优化高仿QQ6.0侧滑菜单(滑动优化)Android开源组件SlidingMenu侧滑菜单使用介绍


--结束END--

本文标题: Android侧滑效果简单实现代码

本文链接: https://www.lsjlt.com/news/23090.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android Drawerlayout实现侧滑菜单效果
    本文实例为大家分享了Drawerlayout侧滑菜单的具体代码,供大家参考,具体内容如下Drawerlayout的xml布局<?xml version="1.0" encoding="utf-8"?><Re...
    99+
    2023-05-30
    drawerlayout 侧滑菜单 roi
  • Android使用DrawerLayout实现侧滑菜单效果
    一、概述DrawerLayout是一个可以方便的实现Android侧滑菜单的组件,我最近开发的项目中也有一个侧滑菜单的功能,于是DrawerLayout就派上用场了。如果你从未使用过DrawerLayout,那么本篇博客将使用一个简单的案例...
    99+
    2023-05-30
    android drawerlayout 侧滑菜单
  • Android 侧滑抽屉菜单的实现代码
    目录前言正文一、创建项目二、添加滑动菜单三、UI美化四、添加导航视图五、菜单分类六、动态菜单七、源码运行效果图: 前言   滑动菜单相信都不会陌生,你可能见...
    99+
    2024-04-02
  • Android中DrawerLayout如何实现侧滑菜单效果
    这篇文章主要为大家展示了“Android中DrawerLayout如何实现侧滑菜单效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Android中DrawerLayout如何实现侧滑菜单效果”...
    99+
    2023-05-30
    drawerlayout android
  • Android 侧滑按钮的实现代码
    目录导入闭包创建RecyclerView子项布局文件布局代码创建RecyclerView适配器描述子项点击事件应用Android侧滑按钮效果如下所示: 导入闭包 将以下语句倒入目录...
    99+
    2024-04-02
  • android实现QQ微信侧滑删除效果
    最近由于项目需求,需要做一个listview中的item策划删除的效果,与是查找资料和参考了一些相关的博客,终于完美实现了策划删除的效果。先看一下效果图(研究了半天竟然没研究出来真机上gif图怎么做,大家将就看一下吧)。 &nbs...
    99+
    2023-05-30
  • android自定义左侧滑出菜单效果
    这里给大家提供一个类似QQ聊天那种可以左侧滑出菜单的自定义控件。希望对大家有帮助。参考了一些网友的做法,自己整理优化了一下,用法非常简单,就一个类,不需要自己写任何的代码,只要添加上...
    99+
    2024-04-02
  • ViewDragHelper实现QQ侧滑效果
    前言       侧滑的实现方式有很多方式来实现,这次总结的ViewDragHelper就是其中一种方式,ViewDragHelper是2013年谷歌I/O大会发布的新的控件,为了...
    99+
    2023-05-30
    viewdraghelper qq侧滑 he
  • Android实现手势滑动和简单动画效果
    一、手势滑动Activity都具有响应触摸事件,也就是说只要触摸Activity,他都会回调一个onTouchEvent()方法。但是在这个方法里无法处理事件,需要配合使用手势识别器(GestureDetector)中的方法onTouchE...
    99+
    2023-05-31
    android 手势滑动 roi
  • Android实现左侧滑动菜单
    本文实例为大家分享了Android实现左侧滑动菜单的具体代码,供大家参考,具体内容如下 效果图: SlideActivity.java: package com.demo.slid...
    99+
    2024-04-02
  • android侧滑菜单怎么实现
    Android侧滑菜单可以通过以下几种方式实现:1. 使用DrawerLayout和NavigationView:DrawerLay...
    99+
    2023-08-18
    android
  • 如何使用android实现左右侧滑菜单效果的方法
    这篇文章主要介绍了如何使用android实现左右侧滑菜单效果的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在android开发中,左右侧滑菜单的开发已成为我们现在开发的...
    99+
    2023-05-30
    android
  • JavaScript代码实现简单日历效果
    本文实例为大家分享了JavaScript实现简单日历效果的具体代码,供大家参考,具体内容如下 效果如下: 代码: <!DOCTYPE html> <html ...
    99+
    2024-04-02
  • Android侧滑导航栏的实例代码
    今天学习的新内容是侧滑导航栏,我想大家肯定都比较熟悉了,因为这个效果在qq里面也有,最近一直跟室友们玩的游戏是快速让自己的头像的点赞量上千。当然我的效果跟qq是没有办法比的,因为那里面的功能是在是太强大了。下面我来展示一下我做的效果截图。我...
    99+
    2023-05-31
    android 侧滑 导航栏
  • Android自定义控件实现简单滑动开关效果
    本文实例为大家分享了Android自定义控件实现简单滑动开关的具体代码,供大家参考,具体内容如下 ToggleButton 滑动开关 项目概述 滑动开关是一个纯粹的自定义控件,上面的...
    99+
    2024-04-02
  • Android怎么实现微信侧滑关闭页面效果
    这篇文章主要介绍了Android怎么实现微信侧滑关闭页面效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。原理在每个Activity里面都有一个底层的View,也就是所谓的r...
    99+
    2023-05-30
  • Android怎么实现侧滑抽屉菜单
    这篇文章将为大家详细讲解有关Android怎么实现侧滑抽屉菜单,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。侧滑抽屉菜单 前言正文一、创建项目二、添加滑动菜单三、UI美化四、添加导航视图五、菜单分类六、动...
    99+
    2023-06-14
  • android 实现侧边弹窗特效代码
    大家好哇,又是我,梦辛工作室的灵,今天来给大家讲解下如何实现 安卓的侧边弹窗, 先大概讲下基本原理吧,其实很简单,就是一个进出动效,用 位移 加 透明度 效果比较好, 比如你的侧边弹...
    99+
    2024-04-02
  • Android自定义ViewGroup实现侧滑菜单
    目录前言一、常用的几种交互方式1.1 事件的拦截处理1.2 自行处理事件的几种方式1.3 子View的滚动与协调交互1.4 ViewGroup之间的嵌套与协调效果二、ViewDrag...
    99+
    2023-01-05
    Android ViewGroup侧滑菜单 Android ViewGroup菜单 Android ViewGroup Android 菜单
  • Android使用DrawerLayout仿QQ6.6版侧滑效果
    一讲到侧滑菜单,我相信大家都会想到一个开源控件SlidingMenu,在google还没有出来DrawerLayout的时候几乎都是使用Slidingmenu来实现侧滑效果,可以说是效果很不错,自从google出了Drawerlayout以...
    99+
    2023-05-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作