package com.mjj.nestedscroll.view; import android.content.Context; import android.support.v4.view.NestedScrollingParent; import android.support.v4.view.NestedScrollingParentHelper; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.FrameLayout; public class MyFrameLayout extends FrameLayout implements NestedScrollingParent { private NestedScrollingParentHelper mNestedScrollingParentHelper; private View headView; private View targetView; private int targetOldTop; private final float RATIO = 0.3f; public MyFrameLayout(Context context) { super(context); init(context); } public MyFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public MyFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { mNestedScrollingParentHelper = new NestedScrollingParentHelper(this); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); headView = getChildAt(0); headView.setTranslationY(-headView.getHeight() / 4); targetView = getChildAt(1); targetOldTop = targetView.getTop(); } @Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { Log.i("asd", "onStartNestedScroll(View " + child.getClass() + ", View " + target.getClass() + ", int " + nestedScrollAxes + ")"); if(nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL && targetView.getScrollY() == 0) { return true; } return false; } @Override public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes) { Log.i("asd", "onNestedScrollAccepted(View child, View target, int " + nestedScrollAxes + ")"); mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, nestedScrollAxes); } @Override public void onStopNestedScroll(final View target) { Log.i("asd", "onStopNestedScroll"); mNestedScrollingParentHelper.onStopNestedScroll(target); } @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { Log.i("asd", "onNestedScroll(View target, int " + dxConsumed + ", int " + dyConsumed + ", int " + dxUnconsumed + ", int" + dyUnconsumed + ")"); } @Override public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { int y = 0; if(targetView.getScrollY() == 0) { y = offset(targetView, dy); } consumed[0] = dx; consumed[1] = y; Log.i("asd", "onNestedPreScroll-" + "dx:" + dx + " dy:" + dy); } @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { Log.i("asd", "onNestedFling"); return false; } @Override public boolean onNestedPreFling(View target, float velocityX, float velocityY) { Log.i("asd", "onNestedPreFling"); return target.getScrollY() == 0; } @Override public int getNestedScrollAxes() { Log.i("asd", "getNestedScrollAxes"); return mNestedScrollingParentHelper.getNestedScrollAxes(); } private int offset(View target, int dy) { int targetTop = target.getTop(); int offset; if(dy > 0) { offset = (targetTop > dy)?dy:targetTop; } else { offset = (targetTop+(-dy) < targetOldTop)?dy: targetTop- targetOldTop; } headView.setTranslationY(headView.getTranslationY() + -offset * RATIO); TopAndBottomOffset(target, -offset); return offset; } private void TopAndBottomOffset(View v, int offset) { int top = v.getTop() + offset; int bottom = v.getBottom(); v.setTop(top); v.setBottom(bottom); } }