Подтвердить что ты не робот

Как работает математика AppBarLayout.ScrollingViewBehavior?

Я бы посмотрел математический поток метода offsetChildAsNeeded в AppBarLayout.ScrollingViewBehavior при запуске изменений прокрутки.

Как это частный метод и частный 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

4b9b3361

Ответ 1

Вы можете перепроектировать этот код, но в конце концов он академичен, потому что мы, простые смертные (т.е. не-Google), не можем получить доступ к приведенным здесь значениям и методам. Думаю, они полагают, что чем меньше их библиотеки мы можем использовать, тем меньше отчетов об ошибках мы будем записывать. Вздох.

Но вот краткое объяснение:

Прежде всего, это строка кода

    final int offset = ablBehavior.getTopBottomOffsetForScrollingSibling();

как представляется, является рудиментарным остатком более ранней версии, поскольку offset никогда не используется. Более новое выражение должно быть немного точнее в других случаях.

ViewCompat.offsetTopAndBottom() не является заданной (абсолютной) операцией, а аддитивной (относительной) операцией. Поэтому допустим обычную логику и учтите, что это поведение по существу ставит прокручиваемое представление непосредственно под маской панели приложения. Как правило, тогда нижняя часть панели приложений и верхняя часть прокрутки имеют одинаковое значение. Поскольку макет панели приложения (зависимость) изменился, и в прокручиваемом представлении (дочернем) пока нет(), затем

    dependency.getBottom() - child.getTop()

- это относительная величина, которую необходимо отрегулировать смещение по вертикали ребенка.

Если мое чтение кода верное, что mOffsetDelta в макете панели приложения не равно нулю, если макет панели приложений имеет смещенный интерполятор. Как правило, панель приложения сама по себе не будет перемещаться параллаксом, поэтому mOffsetDelta равна нулю практически для всех случаев, о которых мы заботимся. getVerticalLayoutGap и getOverlapPixelsForOffset обрабатывать параметры компоновки, такие как 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);
    }

Мне немного легче работать с абсолютными смещениями, а не с относительными смещениями. Таким образом, внедрение поведения прокрутки в основном зависит от определения, где находится зависимое представление, и где должно быть основано прокручиваемое представление.