如何从具有 NestedScrollView 的片段中的 AppBarLayout 禁用 "expand"?

How to disable "expand" from AppBarLayout in fragment that has a NestedScrollView?

我有两个问题:

1) 当我的片段中没有 NestedScrollView 时,我能够阻止 "expand" 功能,但是当我这样做时,它会不断扩展,甚至使用:

appBarLayout.setExpanded(false);
appBarLayout.setActivated(false);

当片段中有 NestedScrollView 时,有什么方法可以防止工具栏展开?

2) 即使我没有 NestedScrollView,当我在工具栏中触摸手指并向下和向上滚动时,我仍然能够展开它。 "expand & collapse" 仍然有效。

当我用手指触摸工具栏并上下滚动时,如何禁用折叠和展开工具栏的动作?

谢谢。

编辑 1(更多信息):

这是我的片段代码,在 FrameLayout 内部。

<android.support.v4.widget.NestedScrollView>

    <LinearLayout>

        <TextView />

        <android.support.v7.widget.RecyclerView />

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

这是我的 activity 结构:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.design.widget.CoordinatorLayout>

        <android.support.design.widget.AppBarLayout>

            <android.support.design.widget.CollapsingToolbarLayout>

                <android.support.v7.widget.Toolbar />

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

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

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

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

    ...

</android.support.v4.widget.DrawerLayout>

编辑 2:现在剩下的唯一问题是: 当片段中有 NestedScrollView 时,有什么方法可以防止工具栏展开?

要阻止用手指在 AppBarLayout 上滚动,您必须使用 DragCallback 界面:

AppBarLayout layout = ...;
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
    @Override
    public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
        return false;
    }
});

要防止 AppBarLayout 由于 NestedScrollView 滚动而滚动,您必须从 NestedScrollView:

中删除该行为
NestedScrollView nestedScrollView = ...;
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) nestedScrollView.getLayoutParams();
params.setBehavior(null);

您可以尝试的另一件事是从 AppBarLayout 子项中删除滚动标志:

AppBarLayout layout = ...;
View child = layout.getChildAt(0);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) child.getLayoutParams();
params.setScrollFlags(0);

到目前为止,我还没有遇到过这个问题,当我需要它可折叠或展开时,通过更改 AppBarLayout height 来解决它。因此,首先,您需要在默认 dimens.xml 文件中定义接下来的两项:

<dimen name="toolbar_height">56dp</dimen>
<dimen name="toolbar_expanded_height">256dp</dimen> // this can be whatever you need

然后防止 AppBarLayoutToolbar 来自 expanding/collapsing 的完整方法是:

public void disableCollapse() {
    appbar.setActivated(false);
    //you will need to hide also all content inside CollapsingToolbarLayout
    //plus you will need to hide title of it
    backdrop.setVisibility(View.GONE);
    shadow.setVisibility(View.GONE);
    collapsingToolbar.setTitleEnabled(false);

    AppBarLayout.LayoutParams p = (AppBarLayout.LayoutParams) collapsingToolbar.getLayoutParams();
    p.setScrollFlags(0);
    collapsingToolbar.setLayoutParams(p);
    collapsingToolbar.setActivated(false);

    CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) appbar.getLayoutParams();
    lp.height = getResources().getDimensionPixelSize(R.dimen.toolbar_height);
    appbar.requestLayout();

    //you also have to setTitle for toolbar
    toolbar.setTitle(title); // or getSupportActionBar().setTitle(title);
}

您可能还需要将状态栏高度添加到工具栏的高度,如果例如您使用fitsSystemWindows=true,那么那么你需要改变

lp.height = getResources().getDimensionPixelSize(R.dimen.toolbar_height);

lp.height = getResources().getDimensionPixelSize(R.dimen.toolbar_height) + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getStatusBarHeight() : 0);

getStatusBarHeight()方法实现是:

protected int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

而且,最后,如果你想再次使你的 AppBarLayoutToolbar collapsable/expandable,你必须使用下一个方法:

public void enableCollapse() {
    appbar.setActivated(true);
    collapsingToolbar.setActivated(true);

    //you will need to show now all content inside CollapsingToolbarLayout
    //plus you will need to show title of it
    backdrop.setVisibility(View.VISIBLE);
    shadow.setVisibility(View.VISIBLE);
    collapsingToolbar.setTitleEnabled(true);

    AppBarLayout.LayoutParams p = (AppBarLayout.LayoutParams) collapsingToolbar.getLayoutParams();
    p.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
    collapsingToolbar.setLayoutParams(p);

    CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) appbar.getLayoutParams();
    lp.height = getResources().getDimensionPixelSize(R.dimen.toolbar_expanded_height);
    appbar.requestLayout();

    //you also have to setTitle for toolbar
    toolbar.setTitle(title); // or getSupportActionBar().setTitle(title);
}

希望对您有所帮助!

在您的特定片段 onViewCreated 方法中添加

 private void disableCollapsing() {
    AppBarLayout layout = ((HomeActivity) getActivity()).appBarLayout;
    View child = layout.getChildAt(0);
    AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) child.getLayoutParams();
    params.setScrollFlags(0);
}

并且 reActive 在被破坏时崩溃

private void enableCollapsing() {
    AppBarLayout layout = ((HomeActivity) getActivity()).appBarLayout;
    View child = layout.getChildAt(0);
    AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) child.getLayoutParams();
    params.setScrollFlags(1);
}