您的位置:首页 > 移动开发 > Android开发

Android实现简单的像QQ一样的侧滑栏

2017-01-16 00:00 204 查看
摘要: 有关自定义view,以及一个强大的类ViewDragHelper的简单应用。

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
);*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐