AppBarLayout.ScrollingViewBehavior的数学如何运作?

时间:2016-10-13 13:02:26

标签: android android-coordinatorlayout android-appbarlayout

我会在运行滚动更改时观察AppBarLayout.ScrollingViewBehavior中offsetChildAsNeeded方法的数学流程。

因为它是私有方法而私有是mOffsetDelta,如何以编程方式监视它们?

(目前尚不清楚该方法如何使用offset。)

private void offsetChildAsNeeded(CoordinatorLayout parent, View child, View dependency) {
    final CoordinatorLayout.Behavior behavior =
                ((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
    if (behavior instanceof Behavior) {
        // Offset the child, pinning it to the bottom the header-dependency, maintaining
        // any vertical gap, and overlap
        final Behavior ablBehavior = (Behavior) behavior;
        final int offset = ablBehavior.getTopBottomOffsetForScrollingSibling();
        ViewCompat.offsetTopAndBottom(child, (dependency.getBottom() - child.getTop())
                + ablBehavior.mOffsetDelta
                + getVerticalLayoutGap()
                - getOverlapPixelsForOffset(dependency));
        }
    }

注意:欢迎并且可以接受回复那些解释有关getTopBottomOffsetForScrollingSibling()(dependency.getBottom() - child.getTop())的数学逻辑以及mOffsetDelta内容的详细信息的回复}

1 个答案:

答案 0 :(得分:3)

您可以对此代码进行反向工程,但最终它的学术成就是因为我们凡人(即非Google)程序员无法访问此处显示的值和方法。我猜他们认为我们实际上使用的库越少,我们提交的错误报告就越少。叹息。

但这里有一个简短的解释:

首先是代码行

    final int offset = ablBehavior.getTopBottomOffsetForScrollingSibling();

似乎是早期版本的遗留残余,因为offset从未实际使用过。在更多情况下,较新的表达式必须更准确。

ViewCompat.offsetTopAndBottom()不是一个设置(绝对)操作,而是一个加法(相对)操作。因此,让我们假设正常的逻辑,并认为这种行为实际上将滚动视图直接放在应用栏布局下面。通常,应用栏的底部和滚动视图的顶部具有相同的值。由于应用栏布局(依赖关系)已更改且滚动视图(子)尚未(尚未),则

    dependency.getBottom() - child.getTop()

是需要调整儿童垂直偏移的相对数量。

如果我对代码的读取是正确的,那么在应用栏布局具有偏移插值器的情况下,应用栏布局中的mOffsetDelta行为仅为非零。通常,应用栏本身不会以视差方式移动,因此对于我们关心的几乎所有情况,mOffsetDelta都为零。 getVerticalLayoutGapgetOverlapPixelsForOffset处理overlapTop等布局参数。

但事实证明,只要这样做,你可以在你自己的行为子类中没有这些边缘情况的情况下完成大部分工作:

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
                                          View dependency) {
        // get the bottom of the app bar layout
        int bottom = dependency.getBottom();

        // position the top of the scrolling view there
        return setTopAndBottomOffset(bottom);
    }

我发现使用绝对偏移而不是相对偏移更容易。因此,实现滚动行为主要是确定从属视图的位置以及滚动视图需要基于此的位置。