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;
}
}
});
tips:ConstraintLayout的动画效果不是通过切换加载两个布局文件来实现的,而是将两个布局文件的布局参数保存下来,然后设置给ConstraintLayout来实现的。