用ViewDragHelper自定义SlideMenu

 记得导入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);
	}
}

猜你喜欢

转载自blog.csdn.net/sinat_40387150/article/details/82146808