Last active
November 21, 2023 06:37
-
-
Save kelvinc1024/b1419de9ad6bbcdbb68bad72ff58e069 to your computer and use it in GitHub Desktop.
Nested Scrolling Layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.support.v4.view.ViewCompat; | |
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, type); | |
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, ViewCompat.TYPE_TOUCH); | |
} | |
} | |
@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, ViewCompat.TYPE_TOUCH); | |
} | |
@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); | |
} | |
} |
I loooooooove you soooooooo much, thx
Cautions
When you use this with coordinator layout on support library version 28.0.0+ version it will have some smoothness nested scrolling issue in some cases
This code tested work and work well in android support version 27.0.1
See issue tracker here
https://issuetracker.google.com/issues/115569344
Doesn't work when user scroll up. You have to implement NestedScrollingChild3 and method dispatchNestedScroll. It will work.
Add this:
override fun onNestedScroll(
target: View,
dxConsumed: Int,
dyConsumed: Int,
dxUnconsumed: Int,
dyUnconsumed: Int,
type: Int,
consumed: IntArray
) {
super.onNestedScroll(
target,
dxConsumed,
dyConsumed,
dxUnconsumed,
dyUnconsumed,
type,
consumed
)
dispatchNestedScroll(
dxConsumed,
dyConsumed,
dxUnconsumed,
dyUnconsumed,
null,
type,
consumed
)
}
override fun dispatchNestedScroll(
dxConsumed: Int,
dyConsumed: Int,
dxUnconsumed: Int,
dyUnconsumed: Int,
offsetInWindow: IntArray?,
type: Int,
consumed: IntArray
) {
mChildHelper.dispatchNestedScroll(
dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow, type, consumed
)
}
Doesn't work when user scroll up. You have to implement NestedScrollingChild3 and method dispatchNestedScroll. It will work. Add this:
override fun onNestedScroll( target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, type: Int, consumed: IntArray ) { super.onNestedScroll( target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed ) dispatchNestedScroll( dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null, type, consumed ) }
override fun dispatchNestedScroll( dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?, type: Int, consumed: IntArray ) { mChildHelper.dispatchNestedScroll( dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow, type, consumed ) }
Thx! It was really helpful :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you,
this was very helpful.