利用ConstraintLayout实现布局改变的动画

ConstraintSet简介
ConstraintSet可以让你方便地通过代码来设置ConstraintLayout的约束。可以利用ConstraintSet创建并保存约束,将这些约束传入一个已经存在的ConstraintLayout。可以利用下面三种方法来创建一个ConstraintSet。

手动指定每一个view的约束

c = new ConstraintSet(); c.connect(....);

从layout中clone

c.clone(context, R.layout.layout1);

从一个已有的ConstraintLayout中clone

c.clone(clayout);

这里需要注意一下,在调用clone()方法的时候,必须保证这个父布局的所有子布局都设置了 id,不然会报如下错误:
因为其要保存所有布局文件中view的约束,如果有些view没有设置id的话,就无法获取这个view的约束了。

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.liuniukeji.lightlanguage/com.mufeng.light.ui.activity.CurriculumClassifyActivity}: java.lang.RuntimeException: All children of ConstraintLayout must have ids to use ConstraintSet
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.RuntimeException: All children of ConstraintLayout must have ids to use ConstraintSet
        at android.support.constraint.ConstraintSet.clone(ConstraintSet.java:688)

TransitionManager
类TransitionManager是用来处理动画的
如果你的API版本在19及以上,那么可以直接使用TransitionManager,否则需要导入support包中的transition。
调用TransitionManager的beginDelayedTransition方法,即可执行动画。TransitionManager中的默认动画效果为AutoTransition。可以看到,默认的动画效果为顺序执行淡出、布局变化、淡入三种动画。如果有需要的话,可以自定义Transition,通过beginDelayedTransition方法传入来使用。

public class AutoTransition extends TransitionSet {
    ...
    private void init() {
        setOrdering(ORDERING_SEQUENTIAL);
        addTransition(new Fade(Fade.OUT)).
                addTransition(new ChangeBounds()).
                addTransition(new Fade(Fade.IN));
    }
}

实操
1.创建两个不同的布局
第一个布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/constraint_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="120dp"
        android:layout_height="29dp"
        android:text="Hello World!"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.473"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.15" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="132dp"
        android:layout_marginBottom="416dp"
        android:text="@string/fd"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.461"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        app:layout_constraintVertical_bias="0.014" />

</androidx.constraintlayout.widget.ConstraintLayout>

第二个布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <Button
        android:id="@+id/button"
        android:layout_width="140dp"
        android:layout_height="78dp"
        android:layout_marginBottom="100dp"
        android:text="@string/sx"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintBottom_toTopOf="@+id/textView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="143dp"
        android:layout_height="35dp"
        android:text="@string/text2"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.488"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.589" />

</androidx.constraintlayout.widget.ConstraintLayout>

对比两个布局文件,可以看到,主要的区别在于,button和textview的约束条件和大小发生了变化。
2.利用ConstraintSet创建并保存两个布局的约束。

final ConstraintSet constraintSet1 = new ConstraintSet();
final ConstraintSet constraintSet2 = new ConstraintSet();

constraintSet2.clone(this, R.layout.ll);
constraintSet1.clone(Constraint);

3.点击button实现布局切换效果

button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TransitionManager.beginDelayedTransition(Constraint, Transition);
                if (ismainact) {
                    constraintSet2.applyTo(Constraint);
                    ismainact = false;
                } else {
                    constraintSet1.applyTo(Constraint);
                    ismainact = true;
                }
            }
        });

利用ConstraintLayout实现布局改变的动画_第1张图片
利用ConstraintLayout实现布局改变的动画_第2张图片
tips:ConstraintLayout的动画效果不是通过切换加载两个布局文件来实现的,而是将两个布局文件的布局参数保存下来,然后设置给ConstraintLayout来实现的。

你可能感兴趣的:(利用ConstraintLayout实现布局改变的动画)