Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collapsing Toolbar bouncing glitch since support lib 26.0.0

Since update of Android Support libs from version 25.4.0 to 26.0.0 (up to 27.0.0) I'm experiencing some weird behaviour in Collapsing Toolbar inside activity.

See difference on these gifs:

  • 25.4.0
  • 26.0.0 (+)

When scrolling up you will see strange bounce of collapsing toolbar.

See code snippet of layout bellow:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    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:background="@color/white_opacity10"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
            app:scrimAnimationDuration="@integer/scrim_animation_short"
            app:titleEnabled="false">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                app:layout_collapseMode="parallax">

                <!-- Here is layout of header -->

            </FrameLayout>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_gravity="top"
                android:layout_marginBottom="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>

            <android.support.design.widget.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_gravity="bottom"
                app:tabGravity="center"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="@color/white"
                app:tabTextColor="@color/white_inactive"/>

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </FrameLayout>

</android.support.design.widget.CoordinatorLayout>

Anybody experiencing same issue? Is this support lib bug, or me doing something wrong?

EDIT:

  • glitch happens only when you fling screen, not when drag
  • for testingyou can pull following project: https://github.com/aaronbond/CollapsingToolbarLayoutExample and encrease support libs to 26 and higher
like image 865
Jarda Havelik Avatar asked Nov 10 '17 12:11

Jarda Havelik


People also ask

How do I disable scrolling in collapsing toolbar layout Android?

How do I disable scrolling in collapsing toolbar layout Android? The solution is simple, we just need to set the app:scrimAnimationDuration=”0" in our collapsing toolbar layout like the below code snippet. Now just run the code and see the results, you will see then there will be no fading animation anymore.

What is collapsing toolbar layout?

CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout .


1 Answers

I experienced something similar, and solved it by defining a custom behaviour for the AppBarLayout.

    <android.support.design.widget.AppBarLayout
        android:id="@+id/main_appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white_40"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
        app:layout_behavior="CustomFlingBehavior">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/main_collapsing"
            android:layout_width="match_parent"
            android:layout_height="144dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <LinearLayout
                android:id="@+id/ll_horizontal_ruler"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_gravity="bottom"
                android:orientation="horizontal"/>

        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

and

public final class FlingBehavior extends AppBarLayout.Behavior {

private static final int TOP_CHILD_FLING_THRESHOLD = 3;
private boolean isPositive;
private boolean enabled = true;

public FlingBehavior() {
    setDragCallback();
}

public FlingBehavior(Context context, AttributeSet attrs) {
    super(context, attrs);
    setDragCallback();
}

private void setDragCallback() {
    setDragCallback(new DragCallback() {
        @Override
        public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
            return enabled;
        }
    });
}

@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, 
                             AppBarLayout child, View target, float 
                             velocityX, float velocityY, boolean 
                             consumed) {
    if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) {
        velocityY = velocityY * -1;
    }
    if (target instanceof RecyclerView && velocityY < 0) {
        final RecyclerView recyclerView = (RecyclerView) target;
        final View firstChild = recyclerView.getChildAt(0);
        final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild);
        consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD;
    }
    return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
}

@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
    super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
    isPositive = dy > 0;
}

public void setEnabled(boolean enabled) {
    this.enabled = enabled;
}

@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
    return enabled && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
}

public boolean isEnabled() {
    return enabled;
}
}

which is based upon the answer here: https://stackoverflow.com/a/40091360/494179

like image 88
saltandpepper Avatar answered Oct 14 '22 12:10

saltandpepper