Использование CollapsingToolbarLayout без setSupportActionBar приведет к неправильной свернутой позиции заголовка - PullRequest
0 голосов
/ 29 июня 2018

Как и в названии, если при использовании панели инструментов без setSupportActionBar в действии, когда панель инструментов свернута, заголовок панели инструментов будет иметь странный верхний отступ, и этот отступ будет 24dp height, который является высотой строки состояния.

Скриншот:
Collapsing issue screenshot

Но если я добавлю setSupportActionBar(toolbar) в onCreate Activity, то эта проблема будет решена.

Файл макета выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".ScrollingActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:toolbarId="@+id/toolbar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                app:title="test"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

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

    <include layout="@layout/content_scrolling" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|end"
        app:srcCompat="@android:drawable/ic_dialog_email" />

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

Я просто использую пример ScrollActivity без больших изменений, просто добавлю приложение: заголовок на панель инструментов и закомментирую setSupportActionBar(toolbar);

версия библиотеки дизайна - 27.1.1

1 Ответ

0 голосов
/ 29 июня 2018

На самом деле, я решил эту проблему, но просто не понимаю, почему Google это делает.

В методе onLayout CollapsingToolbarLayout он сначала рассчитывает положение свернутого заголовка панели инструментов

final int maxOffset = getMaxOffsetForPinChild(
                        mToolbarDirectChild != null ? mToolbarDirectChild : mToolbar);
                ViewGroupUtils.getDescendantRect(this, mDummyView, mTmpRect);
                mCollapsingTextHelper.setCollapsedBounds(
                        mTmpRect.left + (isRtl
                                ? mToolbar.getTitleMarginEnd()
                                : mToolbar.getTitleMarginStart()),
                        mTmpRect.top + maxOffset + mToolbar.getTitleMarginTop(),
                        mTmpRect.right + (isRtl
                                ? mToolbar.getTitleMarginStart()
                                : mToolbar.getTitleMarginEnd()),
                        mTmpRect.bottom + maxOffset - mToolbar.getTitleMarginBottom());

и maxOffset рассчитывается на getMaxOffsetForPinChild, а именно:

final int getMaxOffsetForPinChild(View child) {
    final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child);
    final LayoutParams lp = (LayoutParams) child.getLayoutParams();
    return getHeight()
            - offsetHelper.getLayoutTop()
            - child.getHeight()
            - lp.bottomMargin;
}

проблема в том, что offsetHelper.getLayoutTop () сначала возвращает 0 вместо реальной верхней 24dp, потому что в это время метод onViewLayout offsetHelper не был вызван, он будет вызван после вычисления свернутой позиции заголовка.

    // Update our child view offset helpers. This needs to be done after the title has been
    // setup, so that any Toolbars are in their original position
    for (int i = 0, z = getChildCount(); i < z; i++) {
        getViewOffsetHelper(getChildAt(i)).onViewLayout();
    }

и, согласно комментарию, это поведение типа intend, onViewLayout должен вызываться после установки заголовка. Это точка, которую я не понимаю.

Я думаю, setSupportActionBar сделал что-то, чтобы onLayout снова вызывался, что пересчитает позицию заголовка с правильным LayoutTop. Поэтому я добавляю следующий код:

    final CollapsingToolbarLayout v = findViewById(R.id.toolbar_layout);
    v.post(new Runnable() {
        @Override
        public void run() {
            v.requestLayout();
        }
    });

к методу onCreate действия, и проблема решена.

Теперь я оставлю этот вопрос открытым, так как не думаю, что это элегантное решение, и, возможно, есть какой-то официальный способ решить эту проблему. Или это ошибка, которую разработчик Android не знает?

...