content: package com.quizapp.tollywood.swipelistview;
  
  import android.content.Context;
  import android.support.v4.view.GestureDetectorCompat;
  import android.support.v4.widget.ScrollerCompat;
  import android.util.AttributeSet;
  import android.util.TypedValue;
  import android.view.GestureDetector.OnGestureListener;
  import android.view.GestureDetector.SimpleOnGestureListener;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewTreeObserver.OnGlobalLayoutListener;
  import android.view.animation.Interpolator;
  import android.widget.FrameLayout;
  
  /**
   * 
   * @author baoyz
   * @date 2014-8-23
   * 
   */
  public class SwipeMenuLayout extends FrameLayout {
  
  	private static final int CONTENT_VIEW_ID = 1;
  	private static final int MENU_VIEW_ID = 2;
  
  	private static final int STATE_CLOSE = 0;
  	private static final int STATE_OPEN = 1;
  
  	private View mContentView;
  	private SwipeMenuView mMenuView;
  	private int mDownX;
  	private int state = STATE_CLOSE;
  	private GestureDetectorCompat mGestureDetector;
  	private OnGestureListener mGestureListener;
  	private boolean isFling;
  	private int MIN_FLING = dp2px(15);
  	private int MAX_VELOCITYX = -dp2px(500);
  	private ScrollerCompat mOpenScroller;
  	private ScrollerCompat mCloseScroller;
  	private int mBaseX;
  	private int position;
  	private Interpolator mCloseInterpolator;
  	private Interpolator mOpenInterpolator;
  
  	public SwipeMenuLayout(View contentView, SwipeMenuView menuView) {
  		this(contentView, menuView, null, null);
  	}
  
  	public SwipeMenuLayout(View contentView, SwipeMenuView menuView,
  			Interpolator closeInterpolator, Interpolator openInterpolator) {
  		super(contentView.getContext());
  		mCloseInterpolator = closeInterpolator;
  		mOpenInterpolator = openInterpolator;
  		mContentView = contentView;
  		mMenuView = menuView;
  		mMenuView.setLayout(this);
  		init();
  	}
  
  	// private SwipeMenuLayout(Context context, AttributeSet attrs, int
  	// defStyle) {
  	// super(context, attrs, defStyle);
  	// }
  
  	private SwipeMenuLayout(Context context, AttributeSet attrs) {
  		super(context, attrs);
  	}
  
  	private SwipeMenuLayout(Context context) {
  		super(context);
  	}
  
  	public int getPosition() {
  		return position;
  	}
  
  	public void setPosition(int position) {
  		this.position = position;
  		mMenuView.setPosition(position);
  	}
  
  	private void init() {
  		mGestureListener = new SimpleOnGestureListener() {
  			@Override
  			public boolean onDown(MotionEvent e) {
  				isFling = false;
  				return true;
  			}
  
  			@Override
  			public boolean onFling(MotionEvent e1, MotionEvent e2,
  					float velocityX, float velocityY) {
  				// TODO
  				if ((e1.getX() - e2.getX()) > MIN_FLING
  						&& velocityX < MAX_VELOCITYX) {
  					isFling = true;
  				}
  				// Log.i("byz", MAX_VELOCITYX + ", velocityX = " + velocityX);
  				return super.onFling(e1, e2, velocityX, velocityY);
  			}
  		};
  		mGestureDetector = new GestureDetectorCompat(getContext(),
  				mGestureListener);
  
  		// mScroller = ScrollerCompat.create(getContext(), new
  		// BounceInterpolator());
  		if (mCloseInterpolator != null) {
  			mCloseScroller = ScrollerCompat.create(getContext(),
  					mCloseInterpolator);
  		} else {
  			mCloseScroller = ScrollerCompat.create(getContext());
  		}
  		if (mOpenInterpolator != null) {
  			mOpenScroller = ScrollerCompat.create(getContext(),
  					mOpenInterpolator);
  		} else {
  			mOpenScroller = ScrollerCompat.create(getContext());
  		}
  
  		LayoutParams contentParams = new LayoutParams(
  				LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
  		mContentView.setLayoutParams(contentParams);
  		if (mContentView.getId() < 1) {
  			mContentView.setId(CONTENT_VIEW_ID);
  		}
  
  		mMenuView.setId(MENU_VIEW_ID);
  		mMenuView.setVisibility(View.GONE);
  		mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
  				LayoutParams.MATCH_PARENT));
  
  		addView(mContentView);
  		addView(mMenuView);
  
  		// if (mContentView.getBackground() == null) {
  		// mContentView.setBackgroundColor(Color.WHITE);
  		// }
  
  		// in android 2.x, MenuView height is MATCH_PARENT is not work. 
  		getViewTreeObserver().addOnGlobalLayoutListener(
  				new OnGlobalLayoutListener() {
  					@Override
  					public void onGlobalLayout() {
  						LayoutParams params = (LayoutParams) mMenuView
  								.getLayoutParams();
  						params.height = mContentView.getHeight();
  						mMenuView.setLayoutParams(mMenuView.getLayoutParams());
  						getViewTreeObserver()
  								.removeGlobalOnLayoutListener(this);
  					}
  				});
  		
  		computeScroll();
  //		setBackgroundResource(R.drawable.list_item_bg);
  	}
  
  	@Override
  	protected void onAttachedToWindow() {
  		super.onAttachedToWindow();
  	}
  
  	@Override
  	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  		super.onSizeChanged(w, h, oldw, oldh);
  	}
  
  	public boolean onSwipe(MotionEvent event) {
  		mGestureDetector.onTouchEvent(event);
  		switch (event.getAction()) {
  		case MotionEvent.ACTION_DOWN:
  			mDownX = (int) event.getX();
  			isFling = false;
  			break;
  		case MotionEvent.ACTION_MOVE:
  			// Log.i("byz", "downX = " + mDownX + ", moveX = " + event.getX());
  			int dis = (int) (mDownX - event.getX());
  			if (state == STATE_OPEN) {
  				dis += mMenuView.getWidth();
  			}
  			swipe(dis);
  			break;
  		case MotionEvent.ACTION_UP:
  			if (isFling || (mDownX - event.getX()) > (mMenuView.getWidth() / 2)) {
  				// open
  				smoothOpenMenu();
  			} else {
  				// close
  				smoothCloseMenu();
  				return false;
  			}
  			break;
  		}
  		return true;
  	}
  
  	public boolean isOpen() {
  		return state == STATE_OPEN;
  	}
  
  	@Override
  	public boolean onTouchEvent(MotionEvent event) {
  		return super.onTouchEvent(event);
  	}
  
  	private void swipe(int dis) {
  		if (mMenuView.getVisibility() == View.GONE) {
  			mMenuView.setVisibility(View.VISIBLE);
  		}
  		if (dis > mMenuView.getWidth()) {
  			dis = mMenuView.getWidth();
  		}
  		if (dis < 0) {
  			dis = 0;
  		}
  		mContentView.layout(-dis, mContentView.getTop(),
  				mContentView.getWidth() - dis, getMeasuredHeight());
  		mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
  				mContentView.getWidth() + mMenuView.getWidth() - dis,
  				mMenuView.getBottom());
  	}
  
  	@Override
  	public void computeScroll() {
  		if (state == STATE_OPEN) {
  			if (mOpenScroller.computeScrollOffset()) {
  				swipe(mOpenScroller.getCurrX());
  				postInvalidate();
  			}
  		} else {
  			if (mCloseScroller.computeScrollOffset()) {
  				swipe(mBaseX - mCloseScroller.getCurrX());
  				postInvalidate();
  			}
  		}
  	}
  
  	public void smoothCloseMenu() {
  		state = STATE_CLOSE;
  		mBaseX = -mContentView.getLeft();
  		mCloseScroller.startScroll(0, 0, mBaseX, 0, 350);
  		postInvalidate();
  	}
  
  	public void smoothOpenMenu() {
  		state = STATE_OPEN;
  		mOpenScroller.startScroll(-mContentView.getLeft(), 0,
  				360, 0, 350);
  		postInvalidate();
  	}
  
  	public void closeMenu() {
  		if (mCloseScroller.computeScrollOffset()) {
  			mCloseScroller.abortAnimation();
  		}
  		if (state == STATE_OPEN) {
  			state = STATE_CLOSE;
  			swipe(0);
  		}
  	}
  
  	public void openMenu() {
  		if (state == STATE_CLOSE) {
  			state = STATE_OPEN;
  			swipe(mMenuView.getWidth());
  		}
  	}
  
  	public View getContentView() {
  		return mContentView;
  	}
  
  	public SwipeMenuView getMenuView() {
  		return mMenuView;
  	}
  
  	private int dp2px(int dp) {
  		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
  				getContext().getResources().getDisplayMetrics());
  	}
  
  	@Override
  	protected void onLayout(boolean changed, int l, int t, int r, int b) {
  		mContentView.layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
  		mMenuView.layout(getMeasuredWidth(), 0,
  				getMeasuredWidth() + mMenuView.getMeasuredWidth(),
  				getMeasuredHeight());
  		// bringChildToFront(mContentView);
  	}
  }
  