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

#android #android-coordinatorlayout #android-appbarlayout

#Android #android-coordinatorlayout #android-appbarlayout

Вопрос:

Я бы посмотрел математический поток 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() , of (dependency.getBottom() - child.getTop()) и содержание mOffsetDelta

Комментарии:

1. Было бы лучше, если бы вы объяснили свою конечную цель, а не то, как вы планируете ее достичь.

2. конечная цель — узнать, как работает поведение при изменении прокрутки

3. Скопируйте AppBarLayout.ScrollingViewBehavior класс в свой проект, внесите изменения, укажите AppBarLayout app:layout_behavior на него, получите прибыль.

4. Я пытаюсь это сделать, но из исходного пакета нет видимости для родительского заголовка ScrollingViewBehavior и для mOffsetDelta в AppBarLayout. Поведение.

5. Я бы очень хотел использовать результаты offsetChildAsNeeded в подклассе AppBarLayout.ScrollingViewBehavior . Есть какие-либо обновления по этому поводу?

Ответ №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);
    }
  

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