web-dev-qa-db-fra.com

CollapsingToolbarLayout sous-titre

Puis-je définir le titre d'un CollapsingToolbarLayout via la méthode setTitle ?

Existe-t-il également un moyen de définir un sous-titre?

33
observer

Si vous voulez que le sous-titre passe à Toolbar lorsque le AppBar est complètement réduit, vous devez créer votre CoordinatorLayout.Behaviour Personnalisé comme ceci: Guide Github

Mais si vous voulez juste un texte plus petit derrière le titre lorsque le AppBar est développé, vous pouvez essayer cette disposition:

<Android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true">
    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/appbar"
        Android:layout_width="match_parent"
        Android:layout_height="300dp"
        Android:fitsSystemWindows="true"
        Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <Android.support.design.widget.CollapsingToolbarLayout
            Android:id="@+id/collapsing_toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginBottom="160dp"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                Android:id="@+id/header"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:background="@drawable/quila2"
                Android:fitsSystemWindows="true"
                Android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />
            <TextView
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:textSize="16sp"
                Android:textColor="@Android:color/white"
                Android:layout_marginBottom="32dp"
                Android:layout_marginEnd="64dp"
                Android:layout_marginStart="48dp"
                app:layout_collapseMode="parallax"
                Android:layout_gravity="bottom"
                Android:text="Lorem Ipsum Iran Lorem Ipsum Iran Lorem Ipsum Iran Lorem Ipsum Iran Lorem Ipsum Iran Lorem Ipsum Iran Lorem Ipsum Iran Lorem Ipsum Iran "/>
            <Android.support.v7.widget.Toolbar
                Android:id="@+id/anim_toolbar"
                Android:layout_width="match_parent"
                Android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        </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:scrollbars="none"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_margin="16dp"
            Android:lineSpacingExtra="8dp"
            Android:text="@string/lorem"
            Android:textSize="18sp"/>

    </Android.support.v4.widget.NestedScrollView>

    <Android.support.design.widget.FloatingActionButton
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_margin="10dp"
        Android:clickable="true"
        Android:src="@drawable/abc_ic_search_api_mtrl_alpha"
        app:layout_anchor="@+id/appbar"
        app:layout_anchorGravity="bottom|right|end" />

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

Notez qu'ici, je définis la hauteur AppBar comme 300dp Et que app:expandedTitleMarginBottom Est 160dp Afin que le titre ne descende pas et n'entre pas en conflit avec le sous-titre out. Dans cet exemple, vous devez définir CollapsingToolbarTitle dynamiquement dans le runtime avec la méthode collapsingToolbarTitle.setTitle("My Title");.

Le résultat sera quelque chose comme ceci:

enter image description here

31
Mohamad Amin

Essayez quelque chose comme this , cela fonctionne pour moi, j'ai créé un ViewBehavior personnalisé

@Override
public boolean layoutDependsOn(CoordinatorLayout parent, HeaderView child, View dependency) {
    return dependency instanceof AppBarLayout;
}

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, HeaderView child, View dependency) {
    shouldInitProperties(child, dependency);

    int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange();
    float percentage = Math.abs(dependency.getY()) / (float) maxScroll;

    float childPosition = dependency.getHeight()
            + dependency.getY()
            - child.getHeight()
            - (getToolbarHeight() - child.getHeight()) * percentage / 2;


    childPosition = childPosition - mStartMarginBottom * (1f - percentage);

    CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
    lp.leftMargin = (int) (percentage * mEndMargintLeft) + mStartMarginLeft;
    lp.rightMargin = mMarginRight;
    child.setLayoutParams(lp);

    child.setY(childPosition);

    ...
    return true;
}

et c'est ma mise en page

<Android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="true"
>


<Android.support.design.widget.AppBarLayout
    Android:id="@+id/app_bar_layout"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:fitsSystemWindows="true"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

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

        <ImageView
            Android:id="@+id/image"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:fitsSystemWindows="true"
            Android:scaleType="centerCrop"
            Android:src="@drawable/img_nature"
            app:layout_collapseMode="parallax"
            />

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            >


            <include
                Android:id="@+id/toolbar_header_view"
                layout="@layout/header_view"
                Android:layout_height="wrap_content"
                Android:layout_width="match_parent"
                Android:layout_marginRight="@dimen/header_view_end_margin_right"
                Android:visibility="gone"
                />

        </Android.support.v7.widget.Toolbar>

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

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

<Android.support.v4.widget.NestedScrollView
    Android:id="@+id/scroll"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    >

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

      ...

    </LinearLayout>

</Android.support.v4.widget.NestedScrollView>

<include
    Android:id="@+id/float_header_view"
    layout="@layout/header_view"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
        app:layout_behavior="com.subtitlebehavoir.harcopro.simple.ViewBehavior"
    />

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

Présentation de ViewHeader:

<?xml version="1.0" encoding="utf-8"?>
<com.subtitlebehavoir.harcopro.simple.HeaderView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
>

<!-- Title -->
<TextView
    Android:id="@+id/header_view_title"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:textColor="@Android:color/white"
    Android:textSize="18sp"
    />

<!-- Subtitle -->
<TextView
    Android:id="@+id/header_view_sub_title"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:textColor="@Android:color/white"
    Android:textSize="16sp"
    />


</com.subtitlebehavoir.harcopro.simple.HeaderView>
9
Harco

La prise en charge des sous-titres dans un CollapsingToolbarLayout est une fonctionnalité que je souhaite également, j'ai donc créé une bibliothèque collapsingtoolbarlayout-subtitle :

enter image description here

Utilisez-le comme vous le feriez sur n'importe quel CollapsingToolbarLayout, ajoutez simplement un attribut de sous-titre dessus:

<Android.support.design.widget.CoordinatorLayout
    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.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <com.hendraanggrian.widget.SubtitleCollapsingToolbarLayout
            Android:id="@+id/subtitlecollapsingtoolbarlayout"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            app:contentScrim="?colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:subtitle="CollapsingToolbarLayout"
            app:title="Subtitle">

            <!-- collapsing toolbar content goes here -->

            <Android.support.v7.widget.Toolbar
                Android:layout_width="match_parent"
                Android:layout_height="?actionBarSize"
                app:layout_collapseMode="pin"/>
        </com.hendraanggrian.widget.SubtitleCollapsingToolbarLayout>
    </Android.support.design.widget.AppBarLayout>

    <!-- content goes here -->

</Android.support.design.widget.CoordinatorLayout>
8
Hendra Anggrian

Voici la version modifiée de l'implémentation de Harco ( this ) donnée ci-dessus qui changera également la taille du titre à mesure que nous développons et réduisons la mise en page.

ViewBehavior.Java

public class ViewBehavior extends CoordinatorLayout.Behavior<HeaderView> {

    private static final float MAX_SCALE = 0.5f;

    private Context mContext;

    private int mStartMarginLeft;
    private int mEndMargintLeft;
    private int mMarginRight;
    private int mStartMarginBottom;
    private boolean isHide;

    public ViewBehavior(Context context, AttributeSet attrs) {
        mContext = context;
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, HeaderView child, View dependency) {
        return dependency instanceof AppBarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, HeaderView child, View dependency) {
        shouldInitProperties(child, dependency);

        int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange();
        float percentage = Math.abs(dependency.getY()) / (float) maxScroll;

        // Set scale for the title
        float size = ((1 - percentage) * MAX_SCALE) + 1;
        child.setScaleXTitle(size);
        child.setScaleYTitle(size);

        // Set position for the header view
        float childPosition = dependency.getHeight()
                + dependency.getY()
                - child.getHeight()
                - (getToolbarHeight() - child.getHeight()) * percentage / 2;

        childPosition = childPosition - mStartMarginBottom * (1f - percentage);

        CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
        lp.leftMargin = (int) (percentage * mEndMargintLeft) + mStartMarginLeft;
        lp.rightMargin = mMarginRight;
        child.setLayoutParams(lp);

        child.setY(childPosition);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
            if (isHide && percentage < 1) {
                child.setVisibility(View.VISIBLE);
                isHide = false;
            } else if (!isHide && percentage == 1) {
                child.setVisibility(View.GONE);
                isHide = true;
            }
        }
        return true;
    }

    private void shouldInitProperties(HeaderView child, View dependency) {

        if (mStartMarginLeft == 0)
            mStartMarginLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_left);

        if (mEndMargintLeft == 0)
            mEndMargintLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_left);

        if (mStartMarginBottom == 0)
            mStartMarginBottom = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_bottom);

        if (mMarginRight == 0)
            mMarginRight = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_right);
    }


    public int getToolbarHeight() {
        int result = 0;
        TypedValue tv = new TypedValue();
        if (mContext.getTheme().resolveAttribute(Android.R.attr.actionBarSize, tv, true)) {
            result = TypedValue.complexToDimensionPixelSize(tv.data, mContext.getResources().getDisplayMetrics());
        }
        return result;
    }
}

HeaderView.Java

public class HeaderView extends LinearLayout {

    @Bind(R.id.header_view_title)
    TextView title;

    @Bind(R.id.header_view_sub_title)
    TextView subTitle;

    public HeaderView(Context context) {
        super(context);
    }

    public HeaderView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.Lollipop)
    public HeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        ButterKnife.bind(this);
    }

    public void bindTo(String title) {
        bindTo(title, "");
    }

    public void bindTo(String title, String subTitle) {
        hideOrSetText(this.title, title);
        hideOrSetText(this.subTitle, subTitle);
    }

    private void hideOrSetText(TextView tv, String text) {
        if (text == null || text.equals(""))
            tv.setVisibility(GONE);
        else
            tv.setText(text);
    }

    public void setScaleXTitle(float scaleXTitle) {
        title.setScaleX(scaleXTitle);
        title.setPivotX(0);
    }

    public void setScaleYTitle(float scaleYTitle) {
        title.setScaleY(scaleYTitle);
        title.setPivotY(30);
    }
}
5
Prashant Kedia

J'ai également eu le même problème. À la fin, j'ai créé un LinearLayout qui contient le titre et le sous-titre, puis j'ai défini la propriété ExpandTitleTextAppearance pour qu'elle soit transparente - masquant efficacement le titre de la barre d'outils lorsque la mise en page est développée. En utilisant cette approche, la barre d'outils se replie sur le LinearLayout et à la fin affiche uniquement le titre à l'état réduit.

Le xml complet est ici:

<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.AppBarLayout
    Android:id="@+id/appbar"
    Android:layout_width="match_parent"
    Android:layout_height="@dimen/series_detail_header_height"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:layout_scrollFlags="scroll|exitUntilCollapsed">
    <Android.support.design.widget.CollapsingToolbarLayout
        Android:id="@+id/collapsing_toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:expandedTitleMarginEnd="64dp"
        app:expandedTitleMarginStart="48dp"
        app:expandedTitleTextAppearance="@style/TransparentText"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">
        <FrameLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            app:layout_collapseMode="parallax">
            <ImageView
                Android:id="@+id/image_view"
                Android:layout_width="match_parent"
                Android:layout_height="@dimen/series_detail_header_image_height"
                Android:scaleType="centerCrop"/>
            <LinearLayout
                Android:id="@+id/header_text_layout"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_gravity="bottom"
                Android:background="?attr/colorPrimary"
                Android:gravity="center_vertical"
                Android:minHeight="@dimen/series_detail_text_layout_height"
                Android:orientation="vertical"
                Android:paddingLeft="20dp"
                Android:paddingRight="10dp"
                Android:paddingTop="10dp">
                <TextView
                    Android:id="@+id/title"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:text="My title"
                    Android:textColor="@Android:color/white"
                    Android:textSize="24sp"/>
                <TextView
                    Android:id="@+id/subtitle"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:textColor="@Android:color/white"
                    Android:textSize="17sp"/>
            </LinearLayout>
        </FrameLayout>
        <View
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="@drawable/shape_toolbar_black_gradient"
            app:layout_collapseMode="pin"/>
        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:layout_gravity="top"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            />
    </Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.view.ViewPager
    Android:id="@+id/show_view_pager"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@Android:color/white"
    Android:paddingTop="@dimen/toolbar_height"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/></Android.support.design.widget.CoordinatorLayout>

Assurez-vous que votre style étend également TextAppearance ou l'application se bloquera si votre bibliothèque de support de conception est v22.2.0:

<style name="TransparentText" parent="@Android:style/TextAppearance">
    <item name="Android:textColor">#00666666</item>
</style>

Ce bogue semble avoir été corrigé dans la version 22.2.1 ( https://code.google.com/p/Android/issues/detail?id=178674 ):

4
bkurzius

Voici la version modifiée de l'implémentation de Harco ( this ) avec le titre et les sous-titres centrés lorsqu'ils sont développés.

activity_main.xml

<?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"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true">


    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/app_bar_layout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:fitsSystemWindows="true"
        Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

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

            <ImageView
                Android:id="@+id/image"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:fitsSystemWindows="true"
                Android:scaleType="centerCrop"
                Android:src="@drawable/img_nature"
                app:layout_collapseMode="parallax" />

            <Android.support.v7.widget.Toolbar
                Android:id="@+id/toolbar"
                Android:layout_width="match_parent"
                Android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin">


                <include
                    Android:id="@+id/toolbar_header_view"
                    layout="@layout/header_view"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:layout_marginRight="@dimen/header_view_end_margin_right"
                    Android:visibility="gone" />

            </Android.support.v7.widget.Toolbar>

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

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

    <Android.support.v4.widget.NestedScrollView
        Android:id="@+id/scroll"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:clipToPadding="false"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

            <TextView
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="Hello World!" />

            <TextView
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="Hello World!" />

        </LinearLayout>


    </Android.support.v4.widget.NestedScrollView>

    <include
        Android:id="@+id/float_header_view"
        layout="@layout/header_view"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:layout_behavior="com.subtitlebehavoir.harcopro.simple.ViewBehavior" />

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

dimens.xml

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

    <dimen name="header_view_end_margin_left">56dp</dimen>
    <dimen name="header_view_end_margin_right">14dp</dimen>

    <dimen name="header_view_start_margin_bottom">14dp</dimen>

</resources>

header_view.xml

<?xml version="1.0" encoding="utf-8"?>
<com.subtitlebehavoir.harcopro.simple.HeaderView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content">

    <!-- Title -->
    <TextView
        Android:id="@+id/header_view_title"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:maxLines="1"
        Android:textColor="@Android:color/white"
        Android:textSize="18sp" />

    <!-- Subtitle -->
    <TextView
        Android:id="@+id/header_view_sub_title"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/header_view_title"
        Android:maxLines="1"
        Android:textColor="@Android:color/white"
        Android:textSize="16sp" />


</com.subtitlebehavoir.harcopro.simple.HeaderView>

HeaderView.Java

public class HeaderView extends RelativeLayout {

    @Bind(R.id.header_view_title)
    TextView title;

    @Bind(R.id.header_view_sub_title)
    TextView subTitle;

    Context context;

    public HeaderView(Context context) {
        super(context);
        this.context = context;
    }

    public HeaderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }

    @TargetApi(Build.VERSION_CODES.Lollipop)
    public HeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.context = context;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        ButterKnife.bind(this);
    }

    public void bindTo(String title) {
        bindTo(title, "");
    }

    public void bindTo(String title, String subTitle) {
        hideOrSetText(this.title, title);
        hideOrSetText(this.subTitle, subTitle);
    }

    private void hideOrSetText(TextView tv, String text) {
        if (text == null || text.equals(""))
            tv.setVisibility(GONE);
        else
            tv.setText(text);
    }

    public void setScaleXTitle(float scaleXTitle) {
        title.setScaleX(scaleXTitle);
        title.setPivotX(0);
    }

    public void setScaleYTitle(float scaleYTitle) {
        title.setScaleY(scaleYTitle);
        title.setPivotY(30);
    }

    public TextView getTitle() {
        return title;
    }

    public TextView getSubTitle() {
        return subTitle;
    }
}

et ViewBehavior.Java

public class ViewBehavior extends CoordinatorLayout.Behavior<HeaderView> {

    private static final float MAX_SCALE = 0.5f;

    private Context mContext;

    private int mStartMarginLeftTitle;
    private int mStartMarginLeftSubTitle;
    private int mEndMargintLeft;
    private int mMarginRight;
    private int mStartMarginBottom;
    private boolean isHide;

    public ViewBehavior(Context context, AttributeSet attrs) {
        mContext = context;
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, HeaderView child, View dependency) {
        return dependency instanceof AppBarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, HeaderView child, View dependency) {
        shouldInitProperties(child, dependency);

        int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange();
        float percentage = Math.abs(dependency.getY()) / (float) maxScroll;

        // Set scale for the title
        float size = ((1 - percentage) * MAX_SCALE) + 1;
        child.setScaleXTitle(size);
        child.setScaleYTitle(size);

        // Set position for the header view
        float childPosition = dependency.getHeight()
                + dependency.getY()
                - child.getHeight()
                - (getToolbarHeight() - child.getHeight()) * percentage / 2;

        childPosition = childPosition - mStartMarginBottom * (1f - percentage);
        child.setY(childPosition);

        // Set Margin for title
        RelativeLayout.LayoutParams lpTitle = (RelativeLayout.LayoutParams) child.getTitle().getLayoutParams();
        lpTitle.leftMargin = (int) ((mStartMarginLeftTitle) - (percentage * (mStartMarginLeftTitle - mEndMargintLeft)));

        if (lpTitle.leftMargin < 20) {
            lpTitle.leftMargin = 20;
        }
        lpTitle.rightMargin = mMarginRight;
        child.getTitle().setLayoutParams(lpTitle);

        // Set Margin for subtitle
        RelativeLayout.LayoutParams lpSubTitle = (RelativeLayout.LayoutParams) child.getSubTitle().getLayoutParams();
        lpSubTitle.leftMargin = (int) ((mStartMarginLeftSubTitle) - (percentage * (mStartMarginLeftSubTitle - mEndMargintLeft)));

        if (lpSubTitle.leftMargin < 20) {
            lpSubTitle.leftMargin = 20;
        }
        lpSubTitle.rightMargin = mMarginRight;
        child.getSubTitle().setLayoutParams(lpSubTitle);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
            if (isHide && percentage < 1) {
                child.setVisibility(View.VISIBLE);
                isHide = false;
            } else if (!isHide && percentage == 1) {
                child.setVisibility(View.GONE);
                isHide = true;
            }
        }
        return true;
    }

    private void shouldInitProperties(HeaderView child, View dependency) {

        if (mStartMarginLeftTitle == 0)
            mStartMarginLeftTitle = getStartMarginLeftTitle(child);

        if (mStartMarginLeftSubTitle == 0)
            mStartMarginLeftSubTitle = getStartMarginLeftSubTitle(child);

        if (mEndMargintLeft == 0)
            mEndMargintLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_left);

        if (mStartMarginBottom == 0)
            mStartMarginBottom = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_bottom);

        if (mMarginRight == 0)
            mMarginRight = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_right);
    }

    public int getStartMarginLeftTitle(HeaderView headerView) {
        TextView title = headerView.getTitle();
        DisplayMetrics displaymetrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(displaymetrics);
        int width = displaymetrics.widthPixels;

        int stringWidth = getStingWidth(title);

        int marginLeft = (int) ((width / 2) - ((stringWidth + (stringWidth * MAX_SCALE)) / 2));
        return marginLeft;
    }

    public int getStartMarginLeftSubTitle(HeaderView headerView) {
        TextView subTitle = headerView.getSubTitle();
        DisplayMetrics displaymetrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(displaymetrics);
        int width = displaymetrics.widthPixels;

        int stringWidth = getStingWidth(subTitle);

        int marginLeft = ((width / 2) - (stringWidth / 2));
        return marginLeft;
    }

    public int getStingWidth(TextView textView) {
        Rect bounds = new Rect();
        Paint textPaint = textView.getPaint();
        textPaint.getTextBounds(textView.getText().toString(), 0, textView.getText().toString().length(), bounds);
        return bounds.width();
    }

    public int getToolbarHeight() {
        int result = 0;
        TypedValue tv = new TypedValue();
        if (mContext.getTheme().resolveAttribute(Android.R.attr.actionBarSize, tv, true)) {
            result = TypedValue.complexToDimensionPixelSize(tv.data, mContext.getResources().getDisplayMetrics());
        }
        return result;
    }
}
1
Prashant Kedia