可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
CorodinatorLayout
inside another CoordinatorLayout
such that scrolling the child-view should also scroll the Parent CoordinatorLayout
.
I have a coordinatorLayout
with ViewPager
that contains different Fragment
such that on Scroll
will hide the tabLayout
I have another coordinatorLayout
that has a viewPager
. This fragment
is inflated in ViewPager
of parent fragment(parent Coordinator layout
).
The problem is onScrolling
the child fragment in childViewpager
only reflects in coordinator layout
of child fragment
and not in the Parent coordinator layout
that I need to do to hide the tablayout
.
the structure is:
CoordinatorLayout(p) ->(tablayout(p) & ViewPager(p) -> CoordinatorLayout(c) ->(tablayout(c) & ViewPAger(c) ->recyclerView(cc))) p -> parent; c -> child; cc -> child to child
How to make on scrolling recycler view will affect both coordinator layout so that the toolbar tablayout(p) will be get hides.
回答1:
I know it's an old question. But I searched a long time to include an CoordinatorLayout
in a fragment, which is in another CoordinatorLayout
.
I modified the answer of dev.bmax a little bit to call both coordinator layouts and call the attached behaviors of both layouts.
So here is my solution.
@SuppressWarnings("unused") public class NestedCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild { private NestedScrollingChildHelper mChildHelper; public NestedCoordinatorLayout(Context context) { super(context); mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); } public NestedCoordinatorLayout(Context context, AttributeSet attrs) { super(context, attrs); mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); } public NestedCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); } @Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { /* Enable the scrolling behavior of our own children */ boolean tHandled = super.onStartNestedScroll(child, target, nestedScrollAxes); /* Enable the scrolling behavior of the parent's other children */ return startNestedScroll(nestedScrollAxes) || tHandled; } @Override public void onStopNestedScroll(View target) { /* Disable the scrolling behavior of our own children */ super.onStopNestedScroll(target); /* Disable the scrolling behavior of the parent's other children */ stopNestedScroll(); } @Override public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { int[][] tConsumed = new int[2][2]; super.onNestedPreScroll(target, dx, dy, tConsumed[0]); dispatchNestedPreScroll(dx, dy, tConsumed[1], null); consumed[0] = tConsumed[0][0] + tConsumed[1][0]; consumed[1] = tConsumed[0][1] + tConsumed[1][1]; } @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 boolean onNestedPreFling(View target, float velocityX, float velocityY) { boolean tHandled = super.onNestedPreFling(target, velocityX, velocityY); return dispatchNestedPreFling(velocityX, velocityY) || tHandled; } @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { boolean tHandled = super.onNestedFling(target, velocityX, velocityY, consumed); return dispatchNestedFling(velocityX, velocityY, consumed) || tHandled; } @Override public void setNestedScrollingEnabled(boolean enabled) { mChildHelper.setNestedScrollingEnabled(enabled); } @Override public boolean isNestedScrollingEnabled() { return mChildHelper.isNestedScrollingEnabled(); } @Override public boolean startNestedScroll(int axes) { return mChildHelper.startNestedScroll(axes); } @Override public void stopNestedScroll() { mChildHelper.stopNestedScroll(); } @Override public boolean hasNestedScrollingParent() { return mChildHelper.hasNestedScrollingParent(); } @Override public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow); } @Override public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow); } @Override public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed); } @Override public boolean dispatchNestedPreFling(float velocityX, float velocityY) { return mChildHelper.dispatchNestedPreFling(velocityX, velocityY); } }
回答2:
Here's a simple implementation of a nested coordinator layout.
/** * This variation of CoordinatorLayout also serves as a nested scrolling child, * which supports passing nested scrolling operations to it's parent when it's * own nested scrolling is locked. */ public class NestedCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild { private NestedScrollingChildHelper mChildHelper; private volatile boolean mPassToParent; public NestedCoordinatorLayout(Context context) { super(context); mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); } public NestedCoordinatorLayout(Context context, AttributeSet attrs) { super(context, attrs); mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); } public NestedCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); } /** * Locks the nested scrolling. Further scroll events will * be passed to the nested scrolling parent. */ public void lockNestedScrolling() { mPassToParent = true; } /** * Unlocks the nested scrolling. Further scroll events will * be dispatched to this layout's own scrolling children. */ public void unlockNestedScrolling() { mPassToParent = false; } /* * NestedScrollingParent implementation */ @Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { /* Enable the scrolling behavior of our own children */ super.onStartNestedScroll(child, target, nestedScrollAxes); /* Enable the scrolling behavior of the parent's other children */ startNestedScroll(nestedScrollAxes); /* Start tracking the current scroll */ return true; } @Override public void onStopNestedScroll(View target) { /* Disable the scrolling behavior of our own children */ super.onStopNestedScroll(target); /* Disable the scrolling behavior of the parent's other children */ stopNestedScroll(); } @Override public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { if (mPassToParent) { dispatchNestedPreScroll(dx, dy, consumed, null); } else { super.onNestedPreScroll(target, dx, dy, consumed); } } @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { if (mPassToParent) { dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null); } else { super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); } } @Override public boolean onNestedPreFling(View target, float velocityX, float velocityY) { if (mPassToParent) { return dispatchNestedPreFling(velocityX, velocityY); } else { return super.onNestedPreFling(target, velocityX, velocityY); } } @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { if (mPassToParent) { return dispatchNestedFling(velocityX, velocityY, consumed); } else { return super.onNestedFling(target, velocityX, velocityY, consumed); } } /* * NestedScrollingChild implementation */ @Override public void setNestedScrollingEnabled(boolean enabled) { mChildHelper.setNestedScrollingEnabled(enabled); } @Override public boolean isNestedScrollingEnabled() { return mChildHelper.isNestedScrollingEnabled(); } @Override public boolean startNestedScroll(int axes) { return mChildHelper.startNestedScroll(axes); } @Override public void stopNestedScroll() { mChildHelper.stopNestedScroll(); } @Override public boolean hasNestedScrollingParent() { return mChildHelper.hasNestedScrollingParent(); } @Override public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow); } @Override public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow); } @Override public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed); } @Override public boolean dispatchNestedPreFling(float velocityX, float velocityY) { return mChildHelper.dispatchNestedPreFling(velocityX, velocityY); } }
回答3:
I made this a library, see it on GitHub.
You just use
in your layout.
回答4:
Unfortunately, this is not supported by CoordinatorLayout
.
Check the code in NestedScrollingChildHelper.startNestedScroll()
and CoordinatorLayout.onStartNestedScroll()
, the nested scrolling event is "consumed" if one of Behavior
s of your inner CoordinatorLayout
consumes it, and won't be further propagated.
回答5:
You need to custom your CHILD CoordinatorLayout, let it implement NestedScrollingChild (ori coordinatorlayout didn't implement it) and override some functions to enable dispatching nested scroll event to your PARENT CoordinatorLayout.