Как сделать AppBarLayout плавающим над контентом, как в недавнем дизайне Google - PullRequest
1 голос
/ 13 апреля 2019

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

С другой стороны, мое приложение выглядит следующим образом

Toolbar has its own space so you can not see the list content below it

Как видите, под областью appbarlayout есть список, которыйскрыть содержимое карты под ним.Макет панели приложения имеет прозрачный фон, поэтому не уверен, почему это происходит.

Вот соответствующий файл макета:

<androidx.coordinatorlayout.widget.CoordinatorLayout
            android:id="@+id/content"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:animateLayoutChanges="false"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
                android:id="@+id/refresh"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/timeline"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:animateLayoutChanges="false"
                    tools:listitem="@layout/custom_row_tweet" />

            </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

            <com.google.android.material.appbar.AppBarLayout
                android:id="@+id/appbar"
                android:layout_width="match_parent"
                android:layout_height="@dimen/top_offset"
                android:background="#00000000"
                android:fitsSystemWindows="true"
                app:elevation="0dp">

                <com.google.android.material.card.MaterialCardView
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top|center_horizontal"
                    android:layout_marginStart="8dp"
                    android:layout_marginTop="4dp"
                    android:layout_marginEnd="8dp"
                    android:layout_marginBottom="4dp"
                    android:onClick="searchTweets"
                    app:cardCornerRadius="8dp"
                    app:cardElevation="8dp"
                    app:layout_scrollFlags="scroll|enterAlways">

                    ...

                </com.google.android.material.card.MaterialCardView>

            </com.google.android.material.appbar.AppBarLayout>

            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="16dp"
                android:onClick="addClick"
                android:src="@drawable/ic_tweet"
                android:tag="0"
                app:fabSize="normal"
                app:layout_anchor="@+id/timeline"
                app:layout_anchorGravity="end|bottom" />

        </androidx.coordinatorlayout.widget.CoordinatorLayout>

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

1 Ответ

0 голосов
/ 17 апреля 2019

Я сталкивался с такой же проблемой при попытке что-то подобное. То, чего я смог достичь, это: Верхний отступ вида Recycler = высота строки состояния + высота панели инструментов . К сожалению, я не использовал здесь никакого поведения, и положение панели инструментов фиксировано. Вот как я этого добился:

<FrameLayout 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:background="?primaryColor"
tools:context=".ui.fragments.mainactivity.library.LibraryFragment">

<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:scrollbars="none" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <com.paolovalerdi.abbey.views.StatusBarView
        android:id="@+id/statusBar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/status_bar_padding" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            style="@style/Toolbar"
            android:elevation="0dp"
            app:contentInsetStart="0dp"
            tools:ignore="UnusedAttribute">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <de.hdodenhof.circleimageview.CircleImageView
                    android:id="@+id/userImage"
                    style="@style/ToolbarIcon"
                    android:layout_alignParentStart="true"
                    android:layout_centerVertical="true"
                    android:layout_marginStart="@dimen/default_item_margin"
                    android:padding="8dp"
                    android:src="@drawable/default_artist_image"
                    tools:ignore="ContentDescription" />

                <TextView
                    android:id="@+id/toolbarTile"
                    style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:layout_gravity="center_horizontal"
                    android:singleLine="true"
                    android:text="@string/library"
                    android:textColor="?android:textColorPrimary"
                    tools:ignore="RelativeOverlap,RtlSymmetry" />

                <com.paolovalerdi.abbey.views.IconImageView
                    android:id="@+id/searchIcon"
                    style="@style/ToolbarIcon"
                    android:layout_alignParentEnd="true"
                    android:layout_centerVertical="true"
                    android:layout_marginEnd="@dimen/default_item_margin"
                    android:src="@drawable/ic_search" />

            </RelativeLayout>

        </androidx.appcompat.widget.Toolbar>

        <ViewStub
            android:id="@+id/cab_stub"
            android:layout_width="match_parent"
            android:layout_height="?android:attr/actionBarSize" />

    </FrameLayout>

</LinearLayout>

StatusBarView.Kt

class StatusBarView : View {

constructor(context: Context) : super(context)

constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

constructor(
        context: Context,
        attrs: AttributeSet,
        defStyleAttr: Int
) : super(
        context,
        attrs,
        defStyleAttr
)

override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
    val lp = layoutParams
    lp.height = insets.systemWindowInsetTop
    layoutParams = lp
    return super.onApplyWindowInsets(insets)
}

И все, что вам нужно сделать, это приложить верхний слой к вашему виду переработчика:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    ViewCompat.requestApplyInsets(view)
    ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
        topPadding = insets.systemWindowInsetTop + resources.getDimensionPixelSize(R.dimen.mini_player_height)
        recyclerView.updatePadding(top = topPadding)
        insets
    }
}

Заметил, что я запрашиваю вставки, потому что это делается внутри фрагмента, а затем все, что вам нужно сделать, это просто установить слушателя в корневое представление (или ваше представление переработчика). Также в вашем представлении переработчика должен быть клип android: clipToPadding = "false". Надеюсь, это поможет:)

Я оставлю пост, который помог мне понять, как обращаться со вставками, как профи.

Windows Insets + переходы фрагментов WindowInsets - Слушатели макетов

...