Наложение содержимого над AppBarLayout с использованием нового дизайна материалов

Я хочу добиться чего-то подобного. (не FAB или Snackbar). Как я могу создать макет, накладывая AppBarLayout? Как это! (Например)

AppBarLayout с наложенным содержимым

Нравится Play Маркет:

Как в Play Store

Мой AppBarLayout с CoordinatorLayout и NestedScrollView с RelativeLayout в качестве содержимого выглядит так:

<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:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/_118sdp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsingToolbarLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:contentScrim="@color/mpc_pink"
        app:expandedTitleMarginStart="@dimen/_40sdp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <de.mypostcardstore.widgets.ItemImageView
            android:id="@+id/header"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@color/mpc_pink"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.7" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/article_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:minHeight="?attr/actionBarSize"
            app:contentScrim="@color/mpc_pink"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />


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

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

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:colorBackground"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

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

Заранее спасибо!


comment
Каков реальный вопрос? Вы хотите карту над расширенной панелью инструментов?   -  person Gabriele Mariotti    schedule 24.06.2015
comment
И что вы хотите, чтобы происходило при прокрутке? Судя по вашему коду, вы хотите, чтобы ваш AppBarLayout полностью прокручивался за пределы экрана при прокрутке - это правильно?   -  person ianhanniballake    schedule 24.06.2015
comment
Очень похоже на планшетный дизайн страницы приложения в Google Play.imgur.com/7C30E7P   -  person X7S    schedule 24.06.2015
comment
Не использовали библиотеку поддержки и определенные виджеты, которые вы используете, но пытались ли вы установить положительное дополнение для прокрутки, а затем использовать clipToPadding?   -  person Sahil Dave    schedule 27.06.2015


Ответы (4)


Просто добавьте что-то вроде

app:behavior_overlapTop="64dp"

в ваш NestedScrollView, и он будет размещен над развернутой панелью инструментов.

Кроме того, вы должны добавить что-то вроде

app:expandedTitleMarginBottom="70dp"

в ваш CollapsingToolbarLayout, чтобы заголовок не отображался под наложенным содержимым прокрутки.

person Ander Webbs    schedule 03.07.2015
comment
Это работает и для меня, но в моем случае у меня есть viewpager вместо вложенной прокрутки, и я не хочу, чтобы эта сворачивающаяся панель инструментов прокручивалась и сворачивалась. но не могу найти решение. Пытался переопределить какой-то метод, чтобы отключить перетаскивание, но он перемещает пейджер ниже сворачивающейся панели инструментов. - person P Vartak; 15.11.2018
comment
@PVartak удалось найти решение вашей проблемы? - person hushed_voice; 16.10.2019
comment
@free_style нет. Наконец, я сохранил меньшую область, на которую пользователь может кликнуть. Фактическая проблема с прокруткой так и не решена. - person P Vartak; 16.10.2019

Это довольно просто, на самом деле. Вы можете добиться этого, используя комбинацию ToolBar, FrameLayout и вашего представления контента (может быть ListView, как ваш первый пример, или что-то еще).

Идея состоит в том, чтобы ваш FrameLayout имел тот же цвет, что и ваш ToolBar, создавая иллюзию того, что ToolBar намного больше, чем он есть на самом деле. Тогда все, что осталось сделать, это сделать ваше представление контента последним (или в API 21 и выше: обладать наивысшим атрибутом elevation), чтобы оно выглядело так, как будто оно парит над вышеупомянутым FrameLayout.

Смотрите мою иллюстрацию ниже:

введите здесь описание изображения

Теперь, когда вы поняли основную идею, ниже приведен реальный фрагмент кода XML для выполнения такой задачи. (На самом деле я использую этот макет в одном из своих приложений):

<!-- Somewhere in your layout.xml -->

....

    <android.support.v7.widget.Toolbar
        android:id="@+id/tb_toolbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/abc_action_bar_default_height_material"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:contentInsetStart="72dp"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <!-- This is the 'faux' ToolBar I've been telling you about. This is the part that will be overlaid by the content view below. -->
    <FrameLayout
        android:id="@+id/v_toolbar_extension"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:layout_below="@+id/tb_toolbar"
        android:background="?attr/colorPrimary"
        android:elevation="2dp"/>

    <!-- Normally, I use this FrameLayout as a base for inflating my fragments. You could just use put your content view here. -->
    <FrameLayout
        android:id="@+id/ly_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tb_toolbar"
        android:elevation="3dp"/>

....

Обратите внимание, что у моего ly_content значение высоты выше, чем у v_toolbar_extension. Это то, что даст вам желаемый эффект «наложенной панели инструментов».

И последнее, но не менее важное: вы хотели бы добавить эту строку где-нибудь в onCreate() вашей активности:

/* Assuming mToolbar exists as a reference to your ToolBar in XML. */
setSupportActionBar(mTbToolbar);
getSupportActionBar().setElevation(0);

Что эти коды сделают, так это установят ToolBar высоту на ноль; удаление предустановленных теней, которые были заданы по умолчанию для панелей инструментов. Если вы этого не сделаете, упомянутая тень создаст «шов» между вашими ToolBar и вашими FrameLayout, тем самым разрушив иллюзию того, что эти двое одинаковы.

p.s.. Также важно, чтобы содержимое отображалось с отступом с каждой стороны. При этом ваш вид контента не будет охватывать всю ширину экрана (что сделает этот эффект бесполезным).


Примечание. Я вижу здесь несколько хороших ответов, в которых упоминалось об отсутствии FrameLayout и вместо этого делалось ToolBar выше. Хотя теоретически это может работать так же хорошо, как предложенное мной решение, у вас могут возникнуть проблемы при попытке манипулировать прокруткой; сделав это, вы не сможете разделить ToolBar и его расширение. Вы будете вынуждены либо сделать Toolbar статическими, либо прокрутить все ToolBar целиком (делает прокрутку немного странной).

Добавьте к этому тот факт, что вы не можете легко назначить пользовательский рисунок в Toolbar. Следовательно, трудно следовать примеру Google Play, который вы привели выше. Хотя, если вы используете мое решение, все, что вам нужно сделать, это просто сделать свой Toolbar прозрачным и вместо этого назначить drawable для FrameLayout.

person Hadi Satrio    schedule 29.06.2015
comment
Как бы вы заставили это работать на устройствах до Lollipop? setElevation() не будет работать. - person adao7000; 02.07.2015
comment
В pre-L эти тени были установлены не setElevation(), а путем изменения вашего style.xml. Подробнее см. здесь: stackoverflow.com/q/12246388/1727589 - person Hadi Satrio; 03.07.2015
comment
это не будет выглядеть хорошо, так как панель инструментов будет иметь тень под ней, и когда панель инструментов рухнет, вы увидите разделение между панелью инструментов и макетом кадра, который имеет цвет фона. - person ponnex; 20.02.2016
comment
Не нужно делать этот взлом. Использование атрибута app:behavior_overlapTop может очень легко добиться этого даже в более старых API (согласно библиотеке поддержки). - person sud007; 06.07.2016
comment
спас мою задницу сегодня. app:behavior_overlapTop не работает, когда мы отключаем флаг прокрутки - person hushed_voice; 16.10.2019

У меня было аналогичное требование, и я достиг его, как показано ниже.

Ваша тема активности должна расширять Theme.AppCompat.Light.NoActionBar. Я создал XML-файл макета как:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_main"
    android:layout_width="match_parent"
    android:layout_height="@dimen/action_bar_size_x2"
    android:background="@color/colorPrimary"
    android:minHeight="?attr/actionBarSize" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="15dp"
    android:layout_marginRight="15dp"
    android:layout_marginTop="@dimen/action_bar_size"
    android:orientation="vertical" >

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

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

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:text="@string/app_name"
                android:textSize="24sp" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

И Activity должно быть примерно таким:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar maintoolbar = (Toolbar) findViewById(R.id.toolbar_main);
        setSupportActionBar(maintoolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
}

Я получил такое представление: введите здесь описание изображения

person Akanksha Hegde    schedule 02.07.2015

Я пытался реализовать такие эффекты, как вы упомянули, которые называются Card Toolbar in Android, и это сработало, как и ожидалось. Вот мой макет, взгляните на него:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_material_light" >
<android.support.v7.widget.Toolbar
    android:layout_width="match_parent"
    android:layout_height="@dimen/toolbar_double_height"
    android:background="?attr/colorPrimary" />
<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="@dimen/cardview_toolbar_spacer"
    android:layout_marginRight="@dimen/cardview_toolbar_spacer"
    android:layout_marginTop="?attr/actionBarSize"
    app:cardBackgroundColor="@android:color/white">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <android.support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize" />
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:alpha="0.12"
            android:background="@android:color/black" />
    </LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>

Надеюсь, вы будете вдохновлены.

person SilentKnight    schedule 02.07.2015