How to sync scroll of two CoordinatorLayout + AppBarLayout

后端 未结 2 2076
北海茫月
北海茫月 2020-12-31 14:32

I have an activity with XML.

Something like:




        
相关标签:
2条回答
  • 2020-12-31 14:38

    I face the same problem days ago. Finally, I found a solution from SwipeRefreshLayout. Just extend CoordinatorLayout and implement NestedScrollingChild interface. It works!

    here is my code:

    public class NestedCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild {
    private final NestedScrollingChildHelper mNestedScrollingChildHelper;
    
    private final int[] mParentOffsetInWindow = new int[2];
    private final int[] mParentScrollConsumed = new int[2];
    
    public NestedCoordinatorLayout(Context context) {
        this(context, null, 0);
    }
    
    public NestedCoordinatorLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public NestedCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mNestedScrollingChildHelper = new NestedScrollingChildHelper(this);
        setNestedScrollingEnabled(true);
    }
    
    // NestedScrollingChild
    
    @Override
    public void setNestedScrollingEnabled(boolean enabled) {
        mNestedScrollingChildHelper.setNestedScrollingEnabled(enabled);
    }
    
    @Override
    public boolean isNestedScrollingEnabled() {
        return mNestedScrollingChildHelper.isNestedScrollingEnabled();
    }
    
    @Override
    public boolean startNestedScroll(int axes) {
        return mNestedScrollingChildHelper.startNestedScroll(axes);
    }
    
    @Override
    public void stopNestedScroll() {
        mNestedScrollingChildHelper.stopNestedScroll();
    }
    
    @Override
    public boolean hasNestedScrollingParent() {
        return mNestedScrollingChildHelper.hasNestedScrollingParent();
    }
    
    @Override
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
                                        int dyUnconsumed, int[] offsetInWindow) {
        return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
                dxUnconsumed, dyUnconsumed, offsetInWindow);
    }
    
    @Override
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
        return mNestedScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
    }
    
    @Override
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
        return mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
    }
    
    @Override
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
        return mNestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
    }
    
    @Override
    public void onNestedScrollAccepted(View child, View target, int axes) {
        super.onNestedScrollAccepted(child, target, axes);
    
        // Dispatch up to the nested parent
        startNestedScroll(axes & ViewCompat.SCROLL_AXIS_VERTICAL);
    }
    
    @Override
    public void onStopNestedScroll(View target) {
        super.onStopNestedScroll(target);
        stopNestedScroll();
    }
    
    @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,
                mParentOffsetInWindow);
    }
    
    @Override
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
        super.onNestedPreScroll(target, dx, dy, consumed);
    
        final int[] parentConsumed = mParentScrollConsumed;
        if (dispatchNestedPreScroll(dx - consumed[0], dy - consumed[1], parentConsumed, null)) {
            consumed[0] += parentConsumed[0];
            consumed[1] += parentConsumed[1];
        }
    }
    }
    

    Use it in your fragment's layout (Inner coordinator layout).

    0 讨论(0)
  • 2020-12-31 14:51

    How can I sync scroll of these 2 AppBarLayouts so that the outer appbar collapses either before/after (doesn't matter if it happens before or after) the inside appbar collapses?

    Delete that Fragment's CoordinatorLayout and just use RelativeLayout as a root tag (for Fragment)and then do your stuffs with that ViewPager in the MainActivity.

    For example, use it inside that CoordinatorLayout like this:

    <CoordinatorLayout>
    <android.support.v4.view.ViewPager/>
        <AppbarLayout/>
        <scrollableView/>
        <FloatingActionButton/>
    </CoordinatorLayout>
    

    Github example:

    https://github.com/TheLittleNaruto/SupportDesignExample

    Or perhaps you want to scroll that ViewPager inside the NestedScrollView but, you'll face a problem then use the following code inside it:

    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    

    That's pretty much it.

    A fragment of the ViewPager has a CoordinatorLayout and AppBarLayout+CollapsingToolbarLayout. XML:

    You don't need to use them twice.

    0 讨论(0)
提交回复
热议问题