滚动不传播到带有嵌套CoordinatorLayout的HideBottomViewOnScrollBehavior BottomNavigationView

问题描述 投票:1回答:1

我的MainActivity包含我的主要内容作为ViewPager2以及具有BottomNavigationView的我的hide_bottom_view_on_scroll_behavior。每个ViewPager2子级都使用appbar_scrolling_view_behavior,并且在大多数情况下,滚动子级片段时,这会导致底部导航隐藏,这是所需的行为。

但是,在我的包含CollapsingToolbarLayoutapp: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>

fragment_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>
android android-toolbar androidx android-collapsingtoolbarlayout bottomnavigationview
1个回答
1
投票

问题是您在另一个协调器布局中有一个协调器布局

带有底部Appbar的第一个CoordinatorLayout无法获取滚动数据,因为第一个已经消耗了滚动数据。

您需要做的是创建一种新型的协调器布局,该布局与外部Coordinatorlayout(即嵌套的协调器布局)进行通信。

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

将其用于内部协调器布局,并且所有内容都有望运行:)

© www.soinside.com 2019 - 2024. All rights reserved.