web-dev-qa-db-ja.com

カスタムビューを使用したCollapsingToolbarLayout

CollapsingToolbarLayoutをカスタムビューで実装しようとしていますが、できません。

私がやりたいこと(画像を投稿できないのでimgurにあります):

拡張されたヘッダーは、画像とタイトルのあるプロファイル画面です

enter image description here

(スクロール時に)展開されないため、画像とタイトルはツールバーに表示されます

enter image description here

しかし、私が見たすべてが期待どおりに機能していませんでした

私はこれとロリポップのアニメーションが初めてなので、誰かが私を助けてくれたらとても感謝しています!

(投稿に関連するものがないため、サンプルコードを投稿しません)

21
ChargerDukes

私の解決策

実装するのと同じシナリオがあったので、犬の例から始めて、説明したとおりに動作するようにいくつかの変更を加えました。私のコードは、そのプロジェクトの分岐点として見つけることができます。 https://github.com/hanscappelle/CoordinatorBehaviorExample を参照してください。

enter image description hereenter image description here

最も重要な変更はレイアウトにあります:

<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:id="@+id/main.appbar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    >

    <Android.support.design.widget.CollapsingToolbarLayout
        Android:id="@+id/main.collapsing"
        Android:layout_width="match_parent"
        Android:layout_height="@dimen/expanded_toolbar_height"
        app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
        >

        <FrameLayout
            Android:id="@+id/main.framelayout.title"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_gravity="bottom"
            >

            <LinearLayout
                Android:id="@+id/main.linearlayout.title"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_gravity="bottom|center_horizontal"
                Android:orientation="vertical"
                Android:paddingBottom="@dimen/spacing_small"
                >

                <TextView
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:layout_gravity="center_horizontal"
                    Android:gravity="bottom|center_horizontal"
                    Android:text="@string/tequila_name"
                    Android:textColor="@Android:color/white"
                    Android:textSize="@dimen/textsize_xlarge"
                    />

                <TextView
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:layout_gravity="center_horizontal"
                    Android:layout_marginTop="@dimen/spacing_xxsmall"
                    Android:text="@string/tequila_tagline"
                    Android:textColor="@Android:color/white"
                    />

            </LinearLayout>
        </FrameLayout>
    </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:lineSpacingExtra="@dimen/spacing_xsmall"
        Android:padding="@dimen/spacing_normal"
        Android:text="@string/lorem"
        Android:textSize="@dimen/textsize_medium"
        />

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

<Android.support.v7.widget.Toolbar
    Android:id="@+id/main.toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="?attr/actionBarSize"
    Android:background="@color/primary"
    app:layout_anchor="@id/main.collapsing"
    app:theme="@style/ThemeOverlay.AppCompat.Dark"
    app:title=""
    >

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

        <Space
            Android:layout_width="@dimen/image_final_width"
            Android:layout_height="@dimen/image_final_width"
            />

        <TextView
            Android:id="@+id/main.textview.title"
            Android:layout_width="wrap_content"
            Android:layout_height="match_parent"
            Android:layout_marginLeft="8dp"
            Android:gravity="center_vertical"
            Android:text="@string/tequila_title"
            Android:textColor="@Android:color/white"
            Android:textSize="@dimen/textsize_large"
            />

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

<de.hdodenhof.circleimageview.CircleImageView
    Android:layout_width="@dimen/image_width"
    Android:layout_height="@dimen/image_width"
    Android:layout_gravity="top|center_horizontal"
    Android:layout_marginTop="@dimen/spacing_normal"
    Android:src="@drawable/ninja"
    app:border_color="@Android:color/white"
    app:border_width="@dimen/border_width"
    app:finalHeight="@dimen/image_final_width"
    app:finalXPosition="@dimen/spacing_small"
    app:finalYPosition="@dimen/spacing_small"
    app:finalToolbarHeight="?attr/actionBarSize"
    app:layout_behavior="saulmm.myapplication.AvatarImageBehavior"
    />

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

そして、アバターを元の位置から属性で構成された位置に移動するためだけに最適化したAvatarImageBehaviourクラス。そのため、画像を別の場所から移動する場合は、レイアウト内で移動するだけです。その場合は、AppBarLayoutがまだ兄弟であることを確認してください。そうでない場合は、コード内に見つかりません。

package saulmm.myapplication;

import Android.content.Context;
import Android.content.res.TypedArray;
import Android.support.design.widget.AppBarLayout;
import Android.support.design.widget.CoordinatorLayout;
import Android.util.AttributeSet;
import Android.view.View;
import de.hdodenhof.circleimageview.CircleImageView;

public class AvatarImageBehavior extends CoordinatorLayout.Behavior<CircleImageView> {

// calculated from given layout
private int startXPositionImage;
private int startYPositionImage;
private int startHeight;
private int startToolbarHeight;

private boolean initialised = false;

private float amountOfToolbarToMove;
private float amountOfImageToReduce;
private float amountToMoveXPosition;
private float amountToMoveYPosition;

// user configured params
private float finalToolbarHeight, finalXPosition, finalYPosition, finalHeight;

public AvatarImageBehavior(
        final Context context,
        final AttributeSet attrs) {

    if (attrs != null) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarImageBehavior);
        finalXPosition = a.getDimension(R.styleable.AvatarImageBehavior_finalXPosition, 0);
        finalYPosition = a.getDimension(R.styleable.AvatarImageBehavior_finalYPosition, 0);
        finalHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalHeight, 0);
        finalToolbarHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalToolbarHeight, 0);
        a.recycle();
    }
}

@Override
public boolean layoutDependsOn(
        final CoordinatorLayout parent,
        final CircleImageView child,
        final View dependency) {

    return dependency instanceof AppBarLayout; // change if you want another sibling to depend on
}

@Override
public boolean onDependentViewChanged(
        final CoordinatorLayout parent,
        final CircleImageView child,
        final View dependency) {

    // make child (avatar) change in relation to dependency (toolbar) in both size and position, init with properties from layout
    initProperties(child, dependency);

    // calculate progress of movement of dependency
    float currentToolbarHeight = startToolbarHeight + dependency.getY(); // current expanded height of toolbar
    // don't go below configured min height for calculations (it does go passed the toolbar)
    currentToolbarHeight = currentToolbarHeight < finalToolbarHeight ? finalToolbarHeight : currentToolbarHeight;
    final float amountAlreadyMoved = startToolbarHeight - currentToolbarHeight;
    final float progress = 100 * amountAlreadyMoved / amountOfToolbarToMove; // how much % of expand we reached

    // update image size
    final float heightToSubtract = progress * amountOfImageToReduce / 100;
    CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
    lp.width = (int) (startHeight - heightToSubtract);
    lp.height = (int) (startHeight - heightToSubtract);
    child.setLayoutParams(lp);

    // update image position
    final float distanceXToSubtract = progress * amountToMoveXPosition / 100;
    final float distanceYToSubtract = progress * amountToMoveYPosition / 100;
    float newXPosition = startXPositionImage - distanceXToSubtract;
    //newXPosition = newXPosition < endXPosition ? endXPosition : newXPosition; // don't go passed end position
    child.setX(newXPosition);
    child.setY(startYPositionImage - distanceYToSubtract);

    return true;
}

private void initProperties(
        final CircleImageView child,
        final View dependency) {

    if (!initialised) {
        // form initial layout
        startHeight = child.getHeight();
        startXPositionImage = (int) child.getX();
        startYPositionImage = (int) child.getY();
        startToolbarHeight = dependency.getHeight();
        // some calculated fields
        amountOfToolbarToMove = startToolbarHeight - finalToolbarHeight;
        amountOfImageToReduce = startHeight - finalHeight;
        amountToMoveXPosition = startXPositionImage - finalXPosition;
        amountToMoveYPosition = startYPositionImage - finalYPosition;
        initialised = true;
    }
}
}

ソース

最も一般的な例は、犬が https://github.com/saulmm/CoordinatorBehaviorExample にリストされているものです。これは良い例ですが、実際には、展開されたビューの中央にツールバーがあり、背景画像も移動します。私の例ではすべて削除されました。

別の説明は http://www.devexchanges.info/2016/03/Android-tip-custom-coordinatorlayout.html にありますが、参照されているクラウド/海の背景画像は犬の例の1つは明らかに他の上に構築されています。

私もこれを見つけましたSO賞金付きの質問が授与されましたが、最終的な解決策が何であるかを実際に見つけることができませんでした CollapsingToolbarLayoutのタイトルでアイコンを追加

そして最後に、これは作業を行う作業ライブラリでなければなりません。私はそれをチェックアウトしましたが、最初の画像は中央に配置されておらず、以前見た犬の例に取り組みました。 https://github.com/datalink747/CollapsingAvatarToolbar を参照してください

もっと読む

http://saulmm.github.io/mastering-coordinatorhttp://www.androidauthority.com/using-coordinatorlayout-Android-apps-703720/https://developer.Android.com/reference/Android/support/design/widget/CoordinatorLayout.htmlhttps://guides.codepath.com/Android/handling-scrolls-with-coordinatorlayout

29
hcpl