Android 图像视图的运动场景

Android motion scene for a image view

我是 MotionLayout 的新手。我遵循了一个简单的示例,其中 MotionLayout 包含一个元素,例如 Button,并且很容易为其生成 MotionScene。但是我有一个 MotionLayout 里面有几个元素。

布局是这样的-

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/details_view_scene">

    <ScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/details_image"
                style="@style/detailsImage"
                app:layout_constraintDimensionRatio="h,16:9"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/name_label"
                style="@style/textTitle"
                android:text="@string/name"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/details_image" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/name_value"
                style="@style/textSubTitle"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/name_label" />

            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/like_button"
                style="@style/floatingButton"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:srcCompat="@drawable/ic_profile_like" />

            <ImageView
                android:id="@+id/like_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_profile_like"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                android:visibility=“invisible”/>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</androidx.constraintlayout.motion.widget.MotionLayout>

问题是当按下 id 为 like_button 的浮动操作按钮时,我希望 id 为 like_image 的图像视图可见,并且应该从浮动操作按钮过渡到顶部图像视图ID details_image.

MotionLayout 可以吗?

注意:MotionLayout 仅适用于其直接子项。它不支持嵌套布局层次结构或 activity 转换。 Read more here

所以把你的 MotionLayout 放在 ScrollView 里面

文件:layout_test_like_button.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scroll_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

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

        <ImageView
            android:id="@+id/details_image"
            android:layout_width="0dp"
            android:layout_height="300dp"
            android:background="@color/colorAccent"
            android:src="@drawable/ic_baseline_broken_image_24"
            app:layout_constraintDimensionRatio="h,16:9"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/name_label"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="name"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/details_image" />

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/name_value"
            style="textSubTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/name_label" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/like_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:srcCompat="@drawable/ic_baseline_check_24" />

        <ImageView
            android:id="@+id/like_image"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:background="@color/colorPrimary"
            android:src="@drawable/ic_baseline_image_24" />
    </androidx.constraintlayout.motion.widget.MotionLayout>
</ScrollView>

您希望在按下按钮时移动 imageView -> 使用 onClick 操作。 将targetId设置为Button,并在constraintSetStart & constraintSetEnd

中更改ImageView的布局

文件:layout_test_like_button_scene.xml

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/like_image"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/like_image"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:visibility="visible"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>

    <Transition
        app:constraintSetEnd="@+id/end"
        app:constraintSetStart="@+id/start"
        app:duration="1000">
        <OnClick
            app:clickAction="toggle"
            app:targetId="@id/like_button" />
    </Transition>
</MotionScene>

第一个问题:

After the transition to the end, I want the image to be invisible.

您应该阅读 KeyFrameSet:指定运动序列过程中视图的位置和属性。

在第 0 帧,将图像的 alpha(或可见性)设置为 0.0(不可见), 在第 99 帧附近,将图像的 alpha(或可见性)设置为 1.0(可见), 在第 100 帧,将图像的 alpha(或可见性)设置为 0.0(不可见),

所以当你点击按钮时,图像的alpha将从0 -> 1 -> 0。

第二题:

On first button click, the image moves from bottom to top which is expected. On second button click, the image still stays at the top and clicking on the image moves it down. Is there a way to reset the transition on every start -> end transition

向您的 MotionLayout 添加一个 MotionLayout.TransitionListener,因此当转换完成时,将进度设置为 0(开始状态)。