package com.asha;
import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ViewCompat;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by hzqiujiadi on 15/11/23.
* hzqiujiadi ashqalcn@gmail.com
*/
public class TouchAlwaysTrueLayout extends ViewGroup implements NestedScrollingChild {
private final NestedScrollingChildHelper mScrollingChildHelper;
/**
* Used during scrolling to retrieve the new offset within the window.
*/
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private int mNestedYOffset;
private int mLastMotionY;
public TouchAlwaysTrueLayout(Context context) {
super(context);
mScrollingChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
MotionEvent vtev = MotionEvent.obtain(event);
if (action == MotionEvent.ACTION_DOWN) {
mNestedYOffset = 0;
}
vtev.offsetLocation(0, mNestedYOffset);
switch (action & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mLastMotionY = (int) event.getY();
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
stopNestedScroll();
break;
case MotionEvent.ACTION_MOVE:
final int y = (int) MotionEventCompat.getY(event, 0);
int deltaY = mLastMotionY - y;
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
deltaY -= mScrollConsumed[1];
vtev.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
final int scrolledDeltaY = getScrollY();
final int unconsumedY = deltaY - scrolledDeltaY;
dispatchNestedScroll(0, scrolledDeltaY, 0, unconsumedY, mScrollOffset);
break;
}
return true;
}
public static ViewGroup wrap(View view){
Context context = view.getContext();
TouchAlwaysTrueLayout wrapper = new TouchAlwaysTrueLayout(context);
wrapper.addView(view, LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
return wrapper;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for ( int i = 0 ; i < getChildCount() ; i++ ){
getChildAt(i).layout(l,t,r,b);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec,heightMeasureSpec);
}
public boolean canChildDragDown(PointF pointF){
return canChildDragDownTraversal(this, pointF.x, pointF.y);
}
private boolean canChildDragDownTraversal(View view, float x, float y){
if ( !inside(view, x, y) ) return false;
if ( ViewCompat.canScrollVertically(view,-1) ) return true;
boolean canDragDown;
if ( view instanceof ViewGroup ){
ViewGroup vp = (ViewGroup) view;
int count = vp.getChildCount();
float newX = x - view.getLeft();
float newY = y - view.getTop();
View sub;
for ( int i = 0 ; i < count; i++ ){
sub = vp.getChildAt(i);
canDragDown = canChildDragDownTraversal(sub,newX,newY);
if ( canDragDown ) return true;
}
}
return false;
}
private boolean inside(View view, float x, float y ){
if ( view.getLeft() <= x && view.getRight() >= x && view.getTop() <= y && view.getBottom() >= y )
return true;
else return false;
}
// NestedScrollingChild
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mScrollingChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return mScrollingChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return mScrollingChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mScrollingChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return mScrollingChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
int dyUnconsumed, int[] offsetInWindow) {
return mScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}