记得导入nineoldandroids-2.4.0.jar包
package com.example.slidemenu.view;
import android.animation.FloatEvaluator;
import android.animation.IntEvaluator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.support.v4.widget.ViewDragHelper.Callback;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import com.nineoldandroids.view.ViewHelper;
public class SlideMenu extends FrameLayout {
private View menuView;
private View mainView;
private int slidWidth;
private ViewDragHelper viewDragHelper;
private double RangeWidth;
public State state = State.CLOSE;
public SlideMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public SlideMenu(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SlideMenu(Context context) {
super(context);
init();
}
private void init() {
menuView = getChildAt(0);
mainView = getChildAt(1);
viewDragHelper = ViewDragHelper.create(this, callBack);
floatEvaluator = new FloatEvaluator();
intEvaluator = new IntEvaluator();
}
public enum State {
CLOSE, OPEN;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
menuView = getChildAt(0);
mainView = getChildAt(1);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
slidWidth = getMeasuredWidth();
RangeWidth = slidWidth * 0.6;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return viewDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
viewDragHelper.processTouchEvent(event);
return true;
}
private Callback callBack = new Callback() {
public boolean tryCaptureView(View child, int pointerId) {
// 设置可拖拽的控件
return child == menuView || child == mainView;
}
public int getViewHorizontalDragRange(View child) {
return (int) RangeWidth;
};
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
if (child == mainView) {
if (left < 0)
left = 0;
if (left > RangeWidth) {
left = (int) RangeWidth;
}
}
return left;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top,
int dx, int dy) {
if (changedView == menuView) {
menuView.layout(0, 0, menuView.getMeasuredWidth(),
menuView.getMeasuredHeight());
int newLeft = dx + mainView.getLeft();
if (newLeft < 0)
newLeft = 0;
if (newLeft > RangeWidth)
newLeft = (int) RangeWidth;
mainView.layout(newLeft, 0,
newLeft + mainView.getMeasuredWidth(),
mainView.getMeasuredHeight());
}
float fraction = (float) (mainView.getLeft() / RangeWidth);
executeAnimation(fraction);
if (fraction == 0 && state != State.CLOSE) {
state = State.CLOSE;
if (listener != null) {
System.out.println("listener.onClose();");
listener.onClose();
}
}
if (fraction == 1 && state != State.OPEN) {
state = State.OPEN;
if (listener != null) {
System.out.println("listener.onOpen();");
listener.onOpen();
}
}
// System.out.println("fraction" + fraction + "state" + state);
if (listener != null) {
listener.fractionChange(fraction);
}
super.onViewPositionChanged(changedView, left, top, dx, dy);
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
int mainLeft = mainView.getLeft();
if (mainLeft < RangeWidth / 2) {
// 关闭
close();
} else {
// 开启
open();
}
if (xvel > 200 && Math.abs(xvel) > Math.abs(yvel)) {
open();
}
if (xvel < -200 && Math.abs(xvel) > Math.abs(yvel)) {
close();
}
super.onViewReleased(releasedChild, xvel, yvel);
}
};
private FloatEvaluator floatEvaluator;
private IntEvaluator intEvaluator;
private onStateChangeListener listener;
protected void executeAnimation(float fraction) {
ViewHelper.setScaleX(menuView,
floatEvaluator.evaluate(fraction, 0.6f, 1f));
ViewHelper.setScaleY(menuView,
floatEvaluator.evaluate(fraction, 0.6f, 1f));
ViewHelper.setScaleX(mainView,
floatEvaluator.evaluate(fraction, 1f, 0.6f));
ViewHelper.setScaleY(mainView,
floatEvaluator.evaluate(fraction, 1f, 0.6f));
ViewHelper.setTranslationX(menuView, floatEvaluator.evaluate(fraction,
-menuView.getMeasuredWidth() / 2, 0));
ViewHelper.setAlpha(menuView,
floatEvaluator.evaluate(fraction, 0.5f, 1f));
getBackground().setColorFilter(
(Integer) ColorUtil.evaluateColor(fraction, Color.BLACK,
Color.TRANSPARENT), Mode.SRC_OVER);
}
public void close() {
viewDragHelper.smoothSlideViewTo(mainView, 0, mainView.getTop());
ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
}
public void open() {
viewDragHelper.smoothSlideViewTo(mainView, (int) RangeWidth,
mainView.getTop());
ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
}
//注意,必须实现这个方法,用于滑动
@Override
public void computeScroll() {
if (viewDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
}
super.computeScroll();
}
public void setOnStateChangeListener(onStateChangeListener listener) {
this.listener = listener;
}
public interface onStateChangeListener {
public abstract void onClose();
public abstract void onOpen();
public abstract void fractionChange(float fraction);
}
}