CoordinatorLayout inside another CoordinatorLayout

匿名 (未验证) 提交于 2019-12-03 01:52:01

问题:

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 Behaviors 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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!