Флаги прокрутки в CollapsingToolbarLayout прерывают прокрутку от распространения до HideBottomViewOnScrollBehavior - PullRequest
1 голос
/ 03 ноября 2019

My MainActivity содержит мой основной контент как ViewPager2, а также мой BottomNavigationView, который имеет hide_bottom_view_on_scroll_behavior. Каждый дочерний элемент ViewPager2 использует appbar_scrolling_view_behavior, и в большинстве случаев это заставляет нижнюю навигационную панель скрываться при прокрутке дочернего фрагмента, что является желаемым поведением.

Однако на моем дочернем фрагменте, который содержит CollapsingToolbarLayout с app:layout_scrollFlags="scroll", это поведение не работает. Удаление scrollFlags=scroll приводит к тому, что нижняя навигационная панель работает так, как должна. Это заставляет меня поверить, что по какой-то причине CollapsingToolbarLayout перехватывает поведение прокрутки и не распространяется до нижней навигации.

Есть мысли?

activity_main.xml

<androidx.coordinatorlayout.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:layout_height="match_parent"
    android:layout_width="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/view_pager"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:nestedScrollingEnabled="true"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </FrameLayout>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/main_bottom_navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:paddingStart="12dp"
        android:paddingEnd="12dp"
        app:itemTextColor="?android:textColorPrimary"
        android:layout_marginBottom="36dp"
        app:itemIconTint="@color/nav_icon_tint"
        android:background="@drawable/rounded_background"
        app:backgroundTint="?android:colorPrimaryDark"
        app:labelVisibilityMode="unlabeled"
        app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
        app:menu="@menu/activity_main_navigation"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

frag_devotional.xml (дочерний элемент ViewPager2)

<androidx.coordinatorlayout.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/background"
        android:theme="@style/AppTheme.AppBarOverlay">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="260dp"
            android:fitsSystemWindows="true"
            app:contentScrim="@color/background"
            app:expandedTitleGravity="bottom"
            app:expandedTitleTextAppearance="@style/Toolbar.ExpandedText"
            app:layout_scrollFlags="scroll"
            app:title="@{devotional.title}"
            app:titleTextAppearance="@style/Toolbar.TitleText"
            app:titleTextColor="?android:textColorPrimary"
            app:toolbarId="@+id/toolbar">

            <ImageView
                android:id="@+id/header_logo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:contentDescription="@{devotional.time}"
                android:scaleType="center"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:textAlignment="textStart"
                app:contentScrim="@color/background"
                app:layout_collapseMode="pin"
                app:layout_scrollFlags="scroll"
                app:popupTheme="@style/AppTheme.PopupOverlay"
                app:title="@{devotional.title}" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:id="@+id/scroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/background"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

     ... content ....
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

1 Ответ

1 голос
/ 11 ноября 2019

Проблема в том, что у вас есть Макет Координатора в другом Макете Координатора

первый CoordinatorLayout с нижней панелью приложения не получает scrolldata, потому что первый уже использует его.

то, что вам нужнодля этого необходимо создать новый тип макета координатора, который «взаимодействует с внешним макетом координатора (т. е. вложенным макетом координатора).

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 void onNestedPreScroll(View target, int dx, int dy, int[] consumed, int type) {
    int[][] tConsumed = new int[2][2];
    super.onNestedPreScroll(target, dx, dy, consumed, type);
    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, int type) {
    super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
    dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null);
}

@Override
public void onStopNestedScroll(View target, int type) {
    /* Disable the scrolling behavior of our own children */
    super.onStopNestedScroll(target, type);
    /* Disable the scrolling behavior of the parent's other children  */
    stopNestedScroll();
}

@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes, int type) {
    /* Enable the scrolling behavior of our own children */
    boolean tHandled = super.onStartNestedScroll(child, target, nestedScrollAxes, type);
    /* Enable the scrolling behavior of the parent's other children  */
    return startNestedScroll(nestedScrollAxes) || tHandled;
}

@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 boolean isNestedScrollingEnabled() {
    return mChildHelper.isNestedScrollingEnabled();
}

@Override
public void setNestedScrollingEnabled(boolean enabled) {
    mChildHelper.setNestedScrollingEnabled(enabled);
}

@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);
}}

используйте это для внутреннего макета координатора, и все должно работать с надеждой:)

...