如何在Android中使用ConstraintSet和Java进行动画?

8
我发现使用 ConstraintSet 快速创建 ConstrainLayout Activity 的动画比使用 RelativeLayoutTransitionManager 快得多。

ConstraintSet 使用两个 XML 文件来为一个 Activity 定义起始和目标位置。

我想要创建像这样的内容:

https://media.giphy.com/media/2UwXdWEoLWe9iQMFIY/giphy.gif

但是没有清晰的指示说明如何在 Java 中使用。任何已经做过这个的人都可以向我展示源代码或链接到一些类似的帖子。

感谢阅读本帖。

1个回答

11

使用ConstraintSet可以实现这一点。关键是要有两个布局,一个布局具有屏幕上的UI元素,另一个布局具有屏幕上的元素。现在,您可以使用带有插值器和持续时间的TransitionManager来动画化布局更改。

activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        android:id="@+id/constraint"
        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"
        android:background="#181818"
        tools:context=".MainActivity">

        <ImageView
            android:id="@+id/backgroundImage"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:src="@drawable/mugello"
            android:scaleType="centerCrop"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="JUNE 3, 2018"
            app:layout_constraintRight_toRightOf="@+id/title"
            app:layout_constraintBottom_toBottomOf="@+id/title"
            android:textSize="12sp"
            android:background="#d3d3d3"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:paddingTop="3dp"
            android:paddingBottom="3dp"/>

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="48dp"
            android:background="#F44336"
            android:paddingBottom="8dp"
            android:paddingEnd="24dp"
            android:paddingStart="24dp"
            android:paddingTop="8dp"
            android:text="Mugello Circuit"
            android:textColor="#FFFF"
            android:textSize="45sp"
            app:layout_constraintRight_toLeftOf="@+id/backgroundImage"
            app:layout_constraintTop_toTopOf="parent" />

        <View
            android:id="@+id/fadeBackgroudView"
            android:layout_width="wrap_content"
            android:layout_height="90dp"
            android:foreground="@drawable/gradient_variant"
            app:layout_constraintBottom_toTopOf="@+id/description" />

        <TextView
            android:id="@+id/tap"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="12dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:text="Tap for info"
            android:textSize="15sp"
            android:textColor="#ffffff"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <TextView
            android:id="@+id/description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="The Mugello is a historic region and valley in northern Tuscany, in Italy. It is located to the north of the city of Florence and consists of the northernmost portion of the Metropolitan City of Florence.  It is connected to the separate Santerno river valley by the Futa Pass."
            android:textSize="22sp"
            android:textColor="#FFFF"
            android:background="#181818"
            android:gravity="center"
            android:paddingStart="8dp"
            android:paddingEnd="8dp"
            android:paddingBottom="8dp"
            app:layout_constraintTop_toBottomOf="@+id/backgroundImage"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"/>

    </android.support.constraint.ConstraintLayout>

活动主细节界面.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/backgroundImage"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        android:src="@drawable/mugello"
        app:layout_constraintBottom_toTopOf="@+id/description"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:background="#F44336"
        android:paddingBottom="8dp"
        android:paddingEnd="24dp"
        android:paddingStart="24dp"
        android:paddingTop="8dp"
        android:text="Mugello Circuit"
        android:textColor="#FFFF"
        android:textSize="45sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="JUNE 3, 2018"
        app:layout_constraintRight_toRightOf="@+id/title"
        app:layout_constraintTop_toBottomOf="@+id/title"
        android:textSize="12sp"
        android:background="#d3d3d3"
        android:paddingStart="16dp"
        android:paddingEnd="16dp"
        android:paddingTop="3dp"
        android:paddingBottom="3dp"/>

    <View
        android:id="@+id/fadeBackgroudView"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:foreground="@drawable/gradient"
        app:layout_constraintBottom_toTopOf="@+id/description" />

    <TextView
        android:id="@+id/tap"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:text="Tap for info"
        android:textSize="15sp"
        android:textColor="#ffffff"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="The Mugello is a historic region and valley in northern Tuscany, in Italy. It is located to the north of the city of Florence and consists of the northernmost portion of the Metropolitan City of Florence.  It is connected to the separate Santerno river valley by the Futa Pass."
        android:textSize="22sp"
        android:textColor="#FFFF"
        android:gravity="center"
        android:background="#181818"
        android:paddingStart="8dp"
        android:paddingEnd="8dp"
        android:paddingBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>


</android.support.constraint.ConstraintLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private boolean show = false;

    private ImageView backgroundImage;
    private ConstraintLayout constraint;
    private ConstraintSet constraintSet = new ConstraintSet();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        constraint = findViewById(R.id.constraint);
        backgroundImage = findViewById(R.id.backgroundImage);
        backgroundImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(show)
                    hideComponents(); // if the animation is shown, we hide back the views
                else
                    showComponents() ;// if the animation is NOT shown, we animate the views
            }

        });

    }

    private void showComponents(){
        show = true;

        constraintSet.clone(this, R.layout.activity_main_detail);

        Transition transition = new ChangeBounds();
        transition.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
        transition.setDuration(1000);

        TransitionManager.beginDelayedTransition(constraint, transition);
        constraintSet.applyTo(constraint);
    }

    private void hideComponents(){
        show = false;

        constraintSet.clone(this, R.layout.activity_main);

        Transition transition = new ChangeBounds();
        transition.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
        transition.setDuration(1000);


        TransitionManager.beginDelayedTransition(constraint, transition);
        constraintSet.applyTo(constraint);
    }
}

这是一份有关ConstraintLayout的幻灯片共享:https://speakerdeck.com/camaelon/advanced-animations-and-constraintlayout


我整天都在尝试寻找类似的东西。非常感谢。 - Kyo Huu
1
没问题。希望对你有用。 - Raghunandan
1
请注意,您可能应该保留创建的约束集,而不是每次显示/隐藏时重新创建它们。 - Nicolas Roard
@NicolasRoard 感谢你的建议。是的,可以避免。 - Raghunandan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接