package me.majiajie.viewdraghelper;
import android.content.Context;
import android.graphics.Point;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
/**
* 滑动布局
*/
public class ViewDragHelperLayout extends LinearLayout
{
private ViewDragHelper mViewDragHelper;
private View mFirstView;
private View mSecondView;
private View mThirdiew;
private Point mFirstPoint = new Point();
public ViewDragHelperLayout(Context context) {
super(context);
init();
}
public ViewDragHelperLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ViewDragHelperLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init()
{
mViewDragHelper = ViewDragHelper.create(this,callback);
//设置开启边界触控
mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_ALL);
}
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
mFirstView = getChildAt(0);
mSecondView = getChildAt(1);
mThirdiew = getChildAt(2);
}
/**
* 父布局更新子视图的偏移位置。子视图使用{@link android.widget.Scroller}.
* <p>须调用{@link #invalidate()}触发</p>
*/
@Override
public void computeScroll()
{
if(mViewDragHelper.continueSettling(true))
{
invalidate();
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
mFirstPoint.set(mFirstView.getLeft(),mFirstView.getTop());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
return mViewDragHelper.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
mViewDragHelper.processTouchEvent(event);
return true;
}
ViewDragHelper.Callback callback = new ViewDragHelper.Callback()
{
/**
* 限制View是否可以拖动,true:可以拖动
*/
@Override
public boolean tryCaptureView(View child, int pointerId)
{
return child != mSecondView;
}
/**
* 控制水平移动
* @param child
* @param left 拖动的View即将到达的左边X坐标(坐标是相对父布局的,非整个屏幕)
* @param dx 水平拖动的像素值
* @return 确切移动到的左侧X坐标
*/
@Override
public int clampViewPositionHorizontal(View child, int left, int dx)
{
return left;
}
/**
* 控制垂直移动
* @param child
* @param top 拖动的View即将到达的顶部Y坐标(坐标是相对父布局的,非整个屏幕)
* @param dy 垂直拖动的像素值
* @return 确切移动到的顶部Y坐标
*/
@Override
public int clampViewPositionVertical(View child, int top, int dy)
{
return top;
}
/**
* 当view被捕获时回调
*/
@Override
public void onViewCaptured(View capturedChild, int activePointerId) {
super.onViewCaptured(capturedChild, activePointerId);
}
/**
* 手指释放的时候调用
* @param releasedChild 释放的View
* @param xvel 从开始拖动到放开手指所便宜的X轴像素
* @param yvel 从开始拖动到放开手指所便宜的Y轴像素
*/
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel)
{
if(releasedChild == mFirstView)
{
mViewDragHelper.settleCapturedViewAt(mFirstPoint.x,mFirstPoint.y);
invalidate();
}
}
/**
* 当触摸到边界时回调。
* @param edgeFlags 边界值,如{@link ViewDragHelper#EDGE_LEFT}
*/
@Override
public void onEdgeTouched(int edgeFlags, int pointerId)
{
super.onEdgeTouched(edgeFlags, pointerId);
}
/**
* true的时候会锁住当前的边界,false则unLock。
*/
@Override
public boolean onEdgeLock(int edgeFlags)
{
return super.onEdgeLock(edgeFlags);
}
/**
* 在边界拖动时调用
*/
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId)
{
//使指定View跟随手指拖动
mViewDragHelper.captureChildView(mSecondView,pointerId);
}
/**
* 水平拖动范围限制,返回>0才可拖动
*/
@Override
public int getViewHorizontalDragRange(View child) {
return super.getViewHorizontalDragRange(child);
}
/**
* 垂直拖动范围限制,返回>0才可拖动
*/
@Override
public int getViewVerticalDragRange(View child) {
return super.getViewVerticalDragRange(child);
}
/**
* 改变同一个坐标(x,y)去寻找captureView位置的方法。(具体在:findTopChildUnder方法中)
*/
@Override
public int getOrderedChildIndex(int index) {
return super.getOrderedChildIndex(index);
}
/**
* 当ViewDragHelper状态发生变化时回调(IDLE,DRAGGING,SETTING[自动滚动时])
*/
@Override
public void onViewDragStateChanged(int state) {
super.onViewDragStateChanged(state);
}
/**
* View在父布局中的位置变更
*/
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
}
};
}