Подтвердить что ты не робот

CollapsingToolbarLayout с пользовательским представлением

Я пытаюсь реализовать CollapsingToolbarLayout с пользовательским представлением, но я не могу этого сделать:

Что я хочу сделать (извините, я не могу отправлять изображения, чтобы он на imgur):

Развернутый заголовок представляет собой экран профиля с изображением и заголовком

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

Не разворачивается (при прокрутке), изображение и заголовок будут на панели инструментов

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

Но все, что я видел, не работало, как я ожидал

Я новичок в этом и lollipop анимации, поэтому, если кто-то может мне помочь, я буду очень благодарен!

(я не отправляю образец кода, потому что у меня нет чего-то, что связано с сообщением)

4b9b3361

Ответ 1

Мое решение

У меня был такой же сценарий для реализации, поэтому я начал с примера с собакой и внес некоторые изменения, чтобы он работал точно так, как вы описываете. Мой код можно найти как вилку в этом проекте, см. https://github.com/hanscappelle/CoordinatorBehaviorExample

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

Наиболее важные изменения в макете:

<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, но поскольку это изображение в облаке/море, на которое ссылается, также найдено в примере с собакой, строить поверх другого.

Я также нашел этот вопрос SO с наградой, отмеченной наградой, но не смог узнать, какое окончательное решение было Добавить значок с заголовком в CollapsingToolbarLayout

И, наконец, это должна быть рабочая библиотека, которая выполняет эту работу. Я проверил это, но исходное изображение не было сосредоточено, и я скорее работал на примере собаки, на который я раньше смотрел. См. https://github.com/datalink747/CollapsingAvatarToolbar

Подробнее читайте

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

Ответ 2

Вы можете использовать этот пример кода https://github.com/saulmm/CoordinatorBehaviorExample Saul MM для достижения этого эффекта. Код слишком велик для вставки здесь, поэтому не вставляйте какой-либо код. Надеюсь, это поможет вам.

Ответ 3

Вы можете использовать эту библиотеку, она очень гибкая и у вас есть инструкции на этой странице.