androidx / constraintlayout

ConstraintLayout is an Android layout component which allows you to position and size widgets in a flexible way
Apache License 2.0
1.06k stars 177 forks source link

Image motion is not working as expected the very 1st time using MotionLayout. #782

Closed alirezaeiii closed 1 year ago

alirezaeiii commented 1 year ago

I have a Layout called fragment_detail where I have used motionLayout in it as follow :

 <androidx.constraintlayout.motion.widget.MotionLayout
    android:id="@+id/details_motion"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_show_details">

    <ImageView
        android:id="@+id/details_backdrop"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:imageUrl="@{tmdbItem.backdropUrl}"
        tools:ignore="ContentDescription" />

    <View
        android:id="@+id/details_backdrop_scrim"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@id/details_backdrop"
        app:layout_constraintEnd_toEndOf="@id/details_backdrop"
        app:layout_constraintStart_toStartOf="@id/details_backdrop"
        app:layout_constraintTop_toTopOf="@id/details_backdrop" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/details_poster"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/placeholder"
        android:scaleType="centerCrop"
        android:transformPivotX="0px"
        android:transformPivotY="0px"
        app:imageUrl="@{tmdbItem.posterUrl}" />

    <View
        android:id="@+id/details_gap_filler"
        android:layout_width="match_parent"
        android:layout_height="2px"
        android:background="@color/window_background"
        app:layout_constraintBottom_toTopOf="@id/details_rv"
        tools:ignore="PxUsage" />

    <com.sample.android.tmdb.widget.TopLeftCutoutBackgroundView
        android:id="@+id/details_appbar_background"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:backgroundColor="@color/window_background"
        app:topLeftCutSize="@dimen/details_corner_cutout" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/details_title"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:ellipsize="end"
        android:text="@{tmdbItem.name}"
        android:textAppearance="@style/TextAppearance.AppCompat.Title" />

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/details_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        app:theme="@style/Toolbar" />

   ...

</androidx.constraintlayout.motion.widget.MotionLayout>

Here is scene_show_details xml file :

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

<Transition
    app:constraintSetEnd="@id/end"
    app:constraintSetStart="@id/start"
    app:duration="200">

    <OnSwipe
        app:dragDirection="dragUp"
        app:moveWhenScrollAtTop="true"
        app:touchAnchorId="@id/details_rv"
        app:touchAnchorSide="top" />

    <KeyFrameSet>
        <KeyPosition
            app:framePosition="20"
            app:keyPositionType="deltaRelative"
            app:percentY="0.51"
            app:motionTarget="@id/details_poster" />

        <!-- This looks weird. We need a quick change from elevated to not-so-elevated at 20% so we set 2 key
             attributes, one at 20% and other at 25%. -->
        <KeyAttribute
            android:elevation="@dimen/z_app_bar"
            android:rotation="45"
            android:rotationY="15"
            app:framePosition="20"
            app:motionTarget="@id/details_poster" />

        <KeyAttribute
            android:elevation="@dimen/details_poster_not_elevation"
            app:framePosition="25"
            app:motionTarget="@id/details_poster" />

        <!-- Only elevate the appbar background over the last 25% -->
        <KeyAttribute
            android:elevation="0dp"
            app:framePosition="75"
            app:motionTarget="@id/details_appbar_background" />

    </KeyFrameSet>

</Transition>

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@id/details_backdrop"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@id/details_appbar_background"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Constraint
        android:id="@id/details_backdrop_scrim"
        app:layout_constraintBottom_toBottomOf="@id/details_backdrop"
        app:layout_constraintEnd_toEndOf="@id/details_backdrop"
        app:layout_constraintStart_toStartOf="@id/details_backdrop"
        app:layout_constraintTop_toTopOf="@id/details_backdrop">

        <CustomAttribute
            app:attributeName="background"
            app:customColorDrawableValue="@android:color/transparent" />

    </Constraint>

    <Constraint
        android:id="@id/details_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="0dp"
        app:layout_constraintTop_toTopOf="parent">

    </Constraint>

    <Constraint
        android:id="@id/details_appbar_background"
        android:layout_width="0dp"
        android:layout_height="88dp"
        app:layout_constraintBottom_toBottomOf="@id/details_poster"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Constraint
        android:id="@id/details_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        app:layout_constraintBottom_toTopOf="@id/details_appbar_background"
        app:layout_constraintEnd_toEndOf="@id/details_appbar_background"
        app:layout_constraintStart_toEndOf="@id/details_poster"
        app:layout_constraintTop_toBottomOf="@id/details_appbar_background" />

    <Constraint
        android:id="@id/details_poster"
        android:layout_width="80dp"
        android:layout_height="0dp"
        android:layout_marginStart="@dimen/padding_normal"
        android:layout_marginTop="200dp"
        android:elevation="@dimen/z_app_bar"
        app:layout_constraintDimensionRatio="h,1:1.5"
        app:layout_constraintStart_toStartOf="@id/details_rv"
        app:layout_constraintTop_toTopOf="parent" />

</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@id/details_backdrop"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@id/details_appbar_background"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Constraint
        android:id="@id/details_backdrop_scrim"
        app:layout_constraintBottom_toBottomOf="@id/details_backdrop"
        app:layout_constraintEnd_toEndOf="@id/details_backdrop"
        app:layout_constraintStart_toStartOf="@id/details_backdrop"
        app:layout_constraintTop_toTopOf="@id/details_backdrop">

        <CustomAttribute
            app:attributeName="background"
            app:customColorDrawableValue="@color/status_bar_scrim_translucent_dark" />

    </Constraint>

    <Constraint
        android:id="@id/details_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="@dimen/z_app_bar"
        app:layout_constraintTop_toTopOf="parent">

    </Constraint>

    <Constraint
        android:id="@id/details_appbar_background"
        android:layout_width="0dp"
        android:layout_height="?android:attr/actionBarSize"
        android:elevation="@dimen/z_app_bar"
        app:layout_constraintEnd_toEndOf="@id/details_rv"
        app:layout_constraintStart_toStartOf="@id/details_rv"
        app:layout_constraintTop_toTopOf="parent" />

    <Constraint
        android:id="@id/details_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="48dp"
        android:layout_marginStart="64dp"
        android:elevation="@dimen/z_app_bar"
        app:layout_constraintBottom_toBottomOf="@id/details_appbar_background"
        app:layout_constraintEnd_toEndOf="@id/details_appbar_background"
        app:layout_constraintStart_toStartOf="@id/details_appbar_background"
        app:layout_constraintTop_toTopOf="@id/details_appbar_background" />

    <Constraint
        android:id="@id/details_poster"
        android:layout_width="72dp"
        android:layout_height="0dp"
        android:elevation="@dimen/details_poster_not_elevation"
        app:layout_constraintDimensionRatio="h,1:1.5"
        app:layout_constraintStart_toStartOf="@id/details_title"
        app:layout_constraintTop_toTopOf="parent" />

</ConstraintSet>

The very 1st time that I go to detail screen, details_poster AppCompatImageView is not animated as expected : https://drive.google.com/file/d/1vwlOmNU7qCnkoswTY_QhzEWRAzj1FcH8/view?usp=sharing

As soon as I scroll to bottom of detail screen and move up, details_poster is animated as expected : https://drive.google.com/file/d/1wBLTOwk77dDwRJJhO5RuSF-dp7DGfn11/view?usp=sharing

Why is that? Is there something I missed? Why it start working as expected when I scroll to bottom of screen?

Source code can be found here : https://github.com/alirezaeiii/TMDb-Paging

jafu888 commented 1 year ago

'''app:percentY="0.51"``` What were you trying to achieve with this? Given this the crush in Y this: image is expected.

Why it does not happen on the way back is potentially a bug.

Do you want it to look like that? Why set y but not X?

image

This seems to be the look you want..

In general if you are trying to transform an image during animation. You the "KeyAttributes" scaleX,scaleY,rotation,rotationX,rotationY. They will tend to do what you expect more often.

We will continue to look into the potential bug.

alirezaeiii commented 1 year ago

The problem will be resolved by removing this line : app:layout_constraintDimensionRatio="h,1:1.5" from details_poster Constraint. Thank you for continuing to look into the potential bug. We need to keep app:percentY="0.51" in order to move up details_poster.