How to sync a scroll of two CoordinatorLayout + AppBarLayout

I have activity with XML.

Sort of:

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.design.widget.CoordinatorLayout android:id="@+id/coordinator" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/primary" android:theme="@style/ToolbarStyle" android:gravity="center_vertical" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_scrollFlags="scroll|enterAlways|snap" style="@style/bold" /> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/TabLayoutStyle" android:animateLayoutChanges="true" app:tabGravity="fill" app:tabMode="fixed" app:tabTextAppearance="@style/TabStyle"/> </android.support.design.widget.AppBarLayout> <com.wedmegood.planner.view.XViewPager android:id="@+id/main_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="fill_vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> ... </android.support.v4.widget.DrawerLayout> 

A Fragment of ViewPager has a CoordinatorLayout and AppBarLayout + CollapsingToolbarLayout .

XML fragment:

 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/primaryDark" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapse_toolbar" android:layout_width="match_parent" android:layout_height="@dimen/my_wedding_banner_height" android:minHeight="48dp" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> <RelativeLayout android:id="@+id/banner" android:layout_width="match_parent" android:layout_marginTop="0dp" android:layout_height="match_parent" app:layout_collapseMode="none"> </RelativeLayout> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="bottom" android:animateLayoutChanges="true" app:tabMode="fixed" app:tabGravity="fill" app:tabTextColor="@color/primary" app:tabSelectedTextColor="@color/primary" app:tabIndicatorColor="@color/accent" app:tabIndicatorHeight="4dp" app:tabTextAppearance="@style/TabStyle"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <com.wedmegood.planner.view.XViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout> 

The fragment has a banner RelativeLayout. I want to synchronize the scrolling of these two AppBarLayouts so that the external AppBar collapses either before / after (it doesnโ€™t matter before or after), does the AppBar crash inside? I tried to set and cancel the scroll flags from 2 AppBars depending on their shift offset listener, it works, but does not give a smooth scroll effect. I can completely change the XML fragment while the banner is working fine.

Also, is there a way to change the TabLayout style / call setTabTextColors when CollapsingToolbarLayout collapses / expands?

+5
source share
2 answers

I am facing the same problem days ago. Finally, I found a solution from SwipeRefreshLayout . Just extend the CoordinatorLayout and implement the NestedScrollingChild interface. He 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 a fragment layout.

+4
source

How can I synchronize the scrolling of these 2 AppBarLayouts so that the external appbar is minimized either before / after (it doesnโ€™t matter if this happens before or after) the internal panel of the application is minimized?

Remove this Fragment CoordinatorLayout and just use the RelativeLayout as the root tag (for the Fragment ), and then do your things with the ViewPager in MainActivity .

For example, use it inside the CoordinatorLayout as follows:

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

Github example:

https://github.com/TheLittleNaruto/SupportDesignExample

Or maybe you want to scroll this ViewPager inside a NestedScrollView , but you will run into a problem, and then use the following code inside it:

 app:layout_behavior="@string/appbar_scrolling_view_behavior" 

This is pretty much the case.

The ViewPager snippet has a Layout coordinator and AppBarLayout + CollapsingToolbarLayout. XML:

You do not need to use them twice.

0
source

Source: https://habr.com/ru/post/1241171/


All Articles