CorodinatorLayout inside another CoordinatorLayout such that scrolling the child-view should also scroll the Parent CoordinatorLayout.
Hopefully, this will help others. The idea I implemented during preScroll calculates how much the parent is able to consume, if it is already 0, then call super.onNestedPreScroll.
Here's the code:
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.NestedScrollingChild2;
import android.support.v4.view.NestedScrollingChildHelper;
import android.util.AttributeSet;
import android.view.View;
public class NestedScrollCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild2 {
private NestedScrollingChildHelper mChildHelper;
public NestedScrollCoordinatorLayout(Context context) {
super(context);
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
public NestedScrollCoordinatorLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
public NestedScrollCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
@Override
public boolean isNestedScrollingEnabled() {
return mChildHelper.isNestedScrollingEnabled();
}
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean hasNestedScrollingParent() {
return mChildHelper.hasNestedScrollingParent();
}
@Override
public boolean hasNestedScrollingParent(int type) {
return mChildHelper.hasNestedScrollingParent(type);
}
@Override
public boolean onStartNestedScroll(View child, View target, int axes, int type) {
boolean superResult = super.onStartNestedScroll(child, target, axes, type);
return startNestedScroll(axes, type) || superResult;
}
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
boolean superResult = super.onStartNestedScroll(child, target, nestedScrollAxes);
return startNestedScroll(nestedScrollAxes) || superResult;
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed, int type) {
dispatchNestedPreScroll(dx, dy, consumed, null);
if (consumed[1] == 0) {
super.onNestedPreScroll(target, dx, dy, consumed, type);
}
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
dispatchNestedPreScroll(dx, dy, consumed, null);
if (consumed[1] == 0) {
super.onNestedPreScroll(target, dx, dy, consumed);
}
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null, type);
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null);
}
@Override
public void onStopNestedScroll(View target, int type) {
super.onStopNestedScroll(target, type);
stopNestedScroll(type);
}
@Override
public void onStopNestedScroll(View target) {
super.onStopNestedScroll(target);
stopNestedScroll();
}
@Override
public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
boolean superResult = super.onNestedPreFling(target, velocityX, velocityY);
return dispatchNestedPreFling(velocityX, velocityY) || superResult;
}
@Override
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
boolean superResult = super.onNestedFling(target, velocityX, velocityY, consumed);
return dispatchNestedFling(velocityX, velocityY, consumed) || superResult;
}
@Override
public boolean startNestedScroll(int axes, int type) {
return mChildHelper.startNestedScroll(axes, type);
}
@Override
public boolean startNestedScroll(int axes) {
return mChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mChildHelper.stopNestedScroll();
}
@Override
public void stopNestedScroll(int type) {
mChildHelper.stopNestedScroll(type);
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @Nullable int[] offsetInWindow, int type) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow, type);
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @Nullable int[] offsetInWindow) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed, @Nullable int[] offsetInWindow) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed, @Nullable int[] offsetInWindow, int type) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, type);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
}
See also this gist on GithHub