使用 Google Design Library 时,如何使工具栏进入视图或脱离视图?

How to make the Toolbar snap into view or out of view when using Google Design Library?

我正在尝试实现类似 WhatsApp 的效果,其中工具栏(滚动时)将像磁铁一样夹入视图,或脱离视图。

我的 MainActivity XML:

现在不要误会我的意思,它有效,当我向下滚动时,工具栏被推出视图但说我停止滚动到一半,然后工具栏就坐在那里,一半隐藏在视图之外,另一半在视图中。 .

我要如何解决这个问题,因为我希望它突然消失或进入视图。

编辑:从支持 23.1.0 开始不再需要。请参阅

解决此问题的一种可能方法是将 Behavior 设置自定义为您的 AppBarLayout

<android.support.design.widget.AppBarLayout
    app:layout_behavior="com.myapp.AppBarLayoutSnapBehavior"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    ...

您的 AppBarLayoutSnapBehavior 将通过在滚动停止时添加捕捉逻辑来更改 AppBarLayout.Behavior 的默认行为。 希望下面的代码是不言自明的。

package com.myapp;

public class AppBarLayoutSnapBehavior extends AppBarLayout.Behavior {

    private ValueAnimator mAnimator;
    private boolean mNestedScrollStarted = false;

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

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
                                       View directTargetChild, View target, int nestedScrollAxes) {
        mNestedScrollStarted = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
        if (mNestedScrollStarted && mAnimator != null) {
            mAnimator.cancel();
        }
        return mNestedScrollStarted;
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target) {
        super.onStopNestedScroll(coordinatorLayout, child, target);

        if (!mNestedScrollStarted) {
            return;
        }

        mNestedScrollStarted = false;

        int scrollRange = child.getTotalScrollRange();
        int topOffset = getTopAndBottomOffset();

        if (topOffset <= -scrollRange || topOffset >= 0) {
            // Already fully visible or fully invisible
            return;
        }

        if (topOffset < -(scrollRange / 2f)) {
            // Snap up (to fully invisible)
            animateOffsetTo(-scrollRange);
        } else {
            // Snap down (to fully visible)
            animateOffsetTo(0);
        }
    }

    private void animateOffsetTo(int offset) {
        if (mAnimator == null) {
            mAnimator = new ValueAnimator();
            mAnimator.setInterpolator(new DecelerateInterpolator());
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    setTopAndBottomOffset((int) animation.getAnimatedValue());
                }
            });
        } else {
            mAnimator.cancel();
        }

        mAnimator.setIntValues(getTopAndBottomOffset(), offset);
        mAnimator.start();
    }
}

唯一的问题是,滚动视图(在我的例子中是 RecyclerView)与 Toolbar 一起对齐。我其实很喜欢这样,但我不确定那是你想要的。

此功能已添加到 android 支持库的 23.1.0 版本中。 来自发行说明:

Added edge snapping support to the AppBarLayout class by adding the SCROLL_FLAG_SNAP constant. When scrolling ends, if the view is only partially visible, the view is snapped and scrolled to its closest edge.

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            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="wrap_content"
                    app:layout_scrollFlags="scroll|enterAlways|snap" />
           -----
           -----

更多信息:http://android-developers.blogspot.in/2015/10/android-support-library-231.html

我只是在主 activity 中隐藏操作栏布局并为 CollapsingToolbarLayout 设置跨度。 它对我有用。

主要activity

    setSupportActionBar(mToolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);     
    getSupportActionBar().hide();

    CollapsingToolbarLayout collapsingToolbar =
            (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
    collapsingToolbar.setTitle("Name");
    loadBackdrop();

和layout_activity_main

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/detail_backdrop_height"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|snap"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:expandedTitleMarginStart="48dp"
        app:expandedTitleMarginEnd="64dp">

        <ImageView
            android:id="@+id/backdrop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:fitsSystemWindows="true"
            app:layout_collapseMode="parallax" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin" />

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

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