package com.lgkj.zeng; import android.animation.FloatEvaluator; import android.animation.IntEvaluator; import android.content.Context; import android.support.v4.view.ViewCompat; import android.support.v4.widget.ViewDragHelper; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; /** * Created by Zzm_Pc on 2017/1/10. */ public class DragViewDemo extends FrameLayout { private ViewDragHelper viewDrag; private View iuView; private View fishView; private float fishRange; private float iuRange; private float ratio; private float iuRatio; private FloatEvaluator floatEvaluator; private IntEvaluator intEvaluator; private boolean is = true; private enum OpenState {Close, Open} OpenState nowOpenState = OpenState.Close; private OpenStateListener openStateListener; public DragViewDemo(Context context) { super(context); initial(); } public DragViewDemo(Context context, AttributeSet attrs) { super(context, attrs); initial(); } public DragViewDemo(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initial(); } //加載此佈局 @Override protected void onFinishInflate() { super.onFinishInflate(); iuView = getChildAt(0); fishView = getChildAt(1); } //在onMeasure方法執行完後就會執行該方法 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); fishRange = getMeasuredWidth() * 0.55f; iuRange = getMeasuredWidth() / 2f; Log.i("information", getMeasuredWidth() + " "); } @Override public void computeScroll() { if (viewDrag.continueSettling(true)) { ViewCompat.postInvalidateOnAnimation(DragViewDemo.this); } } //初始化要作的事情,如初始化變量或者一些類。 private void initial() { viewDrag = ViewDragHelper.create(this, new DragCallBack()); floatEvaluator = new FloatEvaluator(); intEvaluator = new IntEvaluator(); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return viewDrag.shouldInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { viewDrag.processTouchEvent(event); return true; } //接口回調 private class DragCallBack extends ViewDragHelper.Callback { //viewdraghelper重要的chong重寫方法 @Override public boolean tryCaptureView(View child, int pointerId) { return child == fishView || child == iuView; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { if (child == fishView) { if (left > fishRange) { left = (int) fishRange; } else if (left < 0) { left = 0; } } else if (child == iuView) { //獲得iuView移動的條件 if (left > 0) left = 0; if (-left > iuRange) left = -(int) iuRange; } return left; } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { super.onViewPositionChanged(changedView, left, top, dx, dy); if (changedView == fishView) { //計算移動距離的比率 ratio = fishView.getLeft() * 1f / fishRange; change(changedView, dx); if (ratio == 0 && nowOpenState != OpenState.Open) { //側欄打開的狀態 nowOpenState=OpenState.Open; if (openStateListener != null) { openStateListener.opened(ratio); } } else if (ratio == 1 && nowOpenState != OpenState.Close) { //側欄關閉 nowOpenState=OpenState.Close; if (openStateListener != null) { openStateListener.closed(ratio); } } else { //正在拖拽側欄中 if (openStateListener != null) { openStateListener.opening(ratio); } } } else if (changedView == iuView) { iuRatio = -iuView.getLeft() / iuRange; changedView.setScaleX(floatEvaluator.evaluate(iuRatio, 1, 0.5)); changedView.setScaleY(floatEvaluator.evaluate(iuRatio, 1, 0.5)); fishView.setScaleX(floatEvaluator.evaluate(iuRatio, 0.8, 1)); fishView.setScaleY(floatEvaluator.evaluate(iuRatio, 0.8, 1)); fishView.layout(intEvaluator.evaluate(iuRatio, (int) fishRange, 0), fishView.getTop(), fishView.getMeasuredWidth() + intEvaluator.evaluate(iuRatio, (int) fishRange, 0), fishView.getBottom() + dy); if (iuRatio == 1 && nowOpenState != OpenState.Open) { //側欄打開的狀態 nowOpenState=OpenState.Open; if (openStateListener != null) { openStateListener.opened(iuRatio); } } else if (iuRatio == 0 && nowOpenState != OpenState.Close) { //側欄關閉 nowOpenState=OpenState.Close; if (openStateListener != null) { openStateListener.closed(iuRatio); } } else { //正在拖拽側欄中 if (openStateListener != null) { openStateListener.opening(iuRatio); } } } } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); if (releasedChild == fishView && releasedChild.getLeft() > fishRange / 2f) { viewDrag.smoothSlideViewTo(releasedChild, (int) fishRange, releasedChild.getTop()); is = false; //刷新 ViewCompat.postInvalidateOnAnimation(DragViewDemo.this); } else if (releasedChild == fishView && releasedChild.getLeft() < fishRange / 2f) { viewDrag.smoothSlideViewTo(releasedChild, 0, releasedChild.getTop()); //刷新 ViewCompat.postInvalidateOnAnimation(DragViewDemo.this); } else if (releasedChild == iuView && -releasedChild.getLeft() > iuRange / 2) { viewDrag.smoothSlideViewTo(releasedChild, (int) -iuRange, releasedChild.getTop()); //刷新 ViewCompat.postInvalidateOnAnimation(DragViewDemo.this); } else if (releasedChild == iuView && -releasedChild.getLeft() < iuRange / 2) { viewDrag.smoothSlideViewTo(releasedChild, 0, releasedChild.getTop()); //刷新 ViewCompat.postInvalidateOnAnimation(DragViewDemo.this); } } } private void change(View view, int dx) { if (view == fishView) { view.setScaleX(floatEvaluator.evaluate(ratio, 1, 0.8)); view.setScaleY(floatEvaluator.evaluate(ratio, 1, 0.8)); if (iuView.getLeft() == 0) { iuView.setTranslationX(floatEvaluator.evaluate(ratio, -iuView.getMeasuredWidth() / 2, 0)); } else { iuView.layout(intEvaluator.evaluate(ratio, (int) -iuRange, 0), iuView.getTop(), iuView.getMeasuredWidth() + intEvaluator.evaluate(ratio, (int) -iuRange, 0), iuView.getBottom()); } iuView.setScaleX(floatEvaluator.evaluate(ratio, 0.5, 1)); iuView.setScaleY(floatEvaluator.evaluate(ratio, 0.5, 1)); } } //設置監聽器,把數據暴露出去 public void setOpenStateListener(OpenStateListener openStateListener) { this.openStateListener = openStateListener; } //側欄的拖拽狀態的監聽接口 public interface OpenStateListener { void opening(float ratio); void closed(float ratio); void opened(float ratio); } } /* Log.i("informationFishview", "iuRange/4------" + iuRange / 4 + " left------:" + left + " dx------:" + dx + " getRight " + fishView.getRight() + " getx:" + fishView.getX() + " getleft:" + fishView.getLeft() + " getRight:" + fishView.getRight() + " getWidth " + fishView.getWidth() + " measureWith " + fishView.getMeasuredWidth() + " ratio:" + ratio );*/