前面有篇文章简单介绍了一下ConstraintLayout,如果有不熟的地方,可以 自行查看 。这里主要介绍一下ConstraintLayout可以实现的动画。
具体什么样的呢? 我们先看一个复杂一点的dome:
在这里插入图片描述

这里的ConstraintLayout动画主要是将XML中的代码转化到Java代码中即可,还是标间简单的,只是官方给的文档不多,也不知道自己学的对不对。先一个一个来吧。

首先需要添加一个transition依赖,作用是使ConstraintLayout动画过渡,不然就没有动画的感觉:

implementation 'com.android.support:transition:28.0.0'

先从简单的来,先看一下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"
    android:id="@+id/id_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/id_tv_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="80dp"
        android:layout_marginTop="90dp"
        android:background="#952"
        android:padding="12dp"
        android:text="TextView 1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/id_tv_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginTop="149dp"
        android:background="#489"
        android:padding="12dp"
        android:text="TextView 2"
        app:layout_constraintLeft_toRightOf="@id/id_tv_1"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/id_tv_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="160dp"
        android:background="#09F"
        android:padding="12dp"
        android:text="TextView 3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/id_tv_1" />
    <Button
        android:id="@+id/id_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:text="apply"
        android:onClick="apply"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" />
    <Button
        android:id="@+id/id_btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="reset"
        android:onClick="reset"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/id_btn" />
</android.support.constraint.ConstraintLayout>

XML解析图为:

Activity需要准备的是,需要两个ConstraintSet来记录改变的ConstraintLayout规则,大致代码如下:

public class ConstraintActivity extends AppCompatActivity {
    private ConstraintLayout constraintLayout;
    private ConstraintSet applyConstraintSet = new ConstraintSet();
    private ConstraintSet resetConstraintSet = new ConstraintSet();
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_constraint);
        constraintLayout = findViewById(R.id.id_main);
        applyConstraintSet.clone(constraintLayout);
        resetConstraintSet.clone(constraintLayout);
    public void apply(View v) {
        //constrainLayout动画过渡
        TransitionManager.beginDelayedTransition(constraintLayout);
    public void reset(View v) {
        TransitionManager.beginDelayedTransition(constraintLayout);
        resetConstraintSet.applyTo(constraintLayout);
1. 要使TextView1 移动到父窗口的左边

在XML代码中,只需要设置TextView的属性:

app:layout_constraintLeft_toLeftOf="parent"

转成Java代码为:

applyConstraintSet.connect(R.id.id_tv_1,ConstraintSet.START, R.id.id_main, ConstraintSet.START, 0);

但是这个属性在XML代码中,TextView1已经有了,我们只需要改变一下TextView的Margin就行了,

那么基本代码是:

public void apply(View v) {
        //constrainLayout动画过渡
        TransitionManager.beginDelayedTransition(constraintLayout);
        //改变TextView的Margin_START 
        applyConstraintSet.setMargin(R.id.id_tv_1, ConstraintSet.START, 1);
        applyConstraintSet.applyTo(constraintLayout);

效果图为:
在这里插入图片描述

2.所有按钮在父控件中间排列

需要首先需要将View的margin设置为0,因为View如果存在Margin,则会影响View位于中间的操作,然后中间设置使用为centerHorizontally,基础代码为:

 public void apply(View v) {
        //constrainLayout动画过渡
        TransitionManager.beginDelayedTransition(constraintLayout);
        applyConstraintSet.setMargin(R.id.id_tv_1, ConstraintSet.START,0);
        applyConstraintSet.setMargin(R.id.id_tv_1, ConstraintSet.END,0);
        applyConstraintSet.setMargin(R.id.id_tv_2, ConstraintSet.START,0);
        applyConstraintSet.setMargin(R.id.id_tv_2, ConstraintSet.END,0);
        applyConstraintSet.setMargin(R.id.id_tv_3, ConstraintSet.START,0);
        applyConstraintSet.setMargin(R.id.id_tv_3, ConstraintSet.END,0);
        applyConstraintSet.centerHorizontally(R.id.id_tv_1, R.id.id_main);
        applyConstraintSet.centerHorizontally(R.id.id_tv_2, R.id.id_main);
        applyConstraintSet.centerHorizontally(R.id.id_tv_3, R.id.id_main);
        applyConstraintSet.applyTo(constraintLayout);

动态图为:
在这里插入图片描述

3.按钮3移动到屏幕中心

上面的移动到水平中心已经知道了centerHorizontally,那么竖直的使用:centerVertically,大致代码:

    public void apply(View v) {
        //constrainLayout动画过渡
        TransitionManager.beginDelayedTransition(constraintLayout);
        applyConstraintSet.setMargin(R.id.id_tv_3, ConstraintSet.START,0);
        applyConstraintSet.setMargin(R.id.id_tv_3, ConstraintSet.TOP,0);
        applyConstraintSet.setMargin(R.id.id_tv_3, ConstraintSet.END,0);
        applyConstraintSet.setMargin(R.id.id_tv_3, ConstraintSet.BOTTOM,0);
        applyConstraintSet.centerHorizontally(R.id.id_tv_3, R.id.id_main);
        applyConstraintSet.centerVertically(R.id.id_tv_3, R.id.id_main);
        applyConstraintSet.applyTo(constraintLayout);

效果动图为:
在这里插入图片描述

4. 将三个TextView的尺寸变为500px

修改View的尺寸,应该使用constrainHeight或者constrainWidth,代码为:

 public void apply(View v) {
        //constrainLayout动画过渡
        TransitionManager.beginDelayedTransition(constraintLayout);
        applyConstraintSet.constrainWidth(R.id.id_tv_1, 500);
        applyConstraintSet.constrainHeight(R.id.id_tv_1,500);
        applyConstraintSet.constrainWidth(R.id.id_tv_2, 600);
        applyConstraintSet.constrainHeight(R.id.id_tv_2,300);
        applyConstraintSet.constrainWidth(R.id.id_tv_3, 700);
        applyConstraintSet.constrainHeight(R.id.id_tv_3,200);
        applyConstraintSet.applyTo(constraintLayout);

实现效果为:
在这里插入图片描述

4. 将TextView2、TextView3设置为Gone,TextView1设置为match_parent

基本代码如下:

    public void apply(View v) {
        //constrainLayout动画过渡
        TransitionManager.beginDelayedTransition(constraintLayout);
	    //设置View为Gone
        applyConstraintSet.setVisibility(R.id.id_tv_2,ConstraintSet.GONE);
        applyConstraintSet.setVisibility(R.id.id_tv_3,ConstraintSet.GONE);
        //将R.id.id_tv_1所有的constraint清除
        applyConstraintSet.clear(R.id.id_tv_1);
  		//与app:layout_constraintLeft_toLeftOf功效一致
        applyConstraintSet.connect(R.id.id_tv_1,ConstraintSet.START, R.id.id_main, ConstraintSet.START, 0);
        applyConstraintSet.connect(R.id.id_tv_1, ConstraintSet.END, R.id.id_main, ConstraintSet.END,0);
        applyConstraintSet.connect(R.id.id_tv_1, ConstraintSet.TOP, R.id.id_main, ConstraintSet.TOP,0);
        applyConstraintSet.connect(R.id.id_tv_1, ConstraintSet.BOTTOM, R.id.id_main, ConstraintSet.BOTTOM,0);
        applyConstraintSet.applyTo(constraintLayout);

或者直接:

applyConstraintSet.constrainWidth(R.id.id_tv_1,DeviceUtils.getDeviceWidth());
applyConstraintSet.constrainHeight(R.id.id_tv_1,DeviceUtils.getDeviceHeight);

结果显示图为:
在这里插入图片描述

5.显示layout_weight效果

先来看一下我们需要实现的效果吧:

ConstraintSet.CHAIN_SPREADConstraintSet.CHAIN_SPREAD_INSIDEConstraintSet.CHAIN_PACKED
在这里插入图片描述在这里插入图片描述

这个代码都差不多,其实说白只需要明白XML中代码怎么写,这就容易了:

<TextView
        android:id="@+id/id_tv_1"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:background="#278"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/id_tv_2" />
    <TextView
        android:id="@+id/id_tv_2"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:background="#786"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/id_tv_1"
        app:layout_constraintRight_toLeftOf="@id/id_tv_3" />
    <TextView
        android:id="@+id/id_tv_3"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:background="#d08"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/id_tv_2"
        app:layout_constraintRight_toRightOf="parent" />

转成Java代码为:

    public void apply(View v) {
        //constrainLayout动画过渡
        TransitionManager.beginDelayedTransition(constraintLayout);
        applyConstraintSet.clear(R.id.id_tv_1);
        applyConstraintSet.clear(R.id.id_tv_2);
        applyConstraintSet.clear(R.id.id_tv_3);
        //R.id.id_tv_1左边与父布局左边对齐
        applyConstraintSet.connect(R.id.id_tv_1, ConstraintSet.START, R.id.id_main, ConstraintSet.START, 0);
        //R.id.id_tv_3右边与父布局右边对齐
        applyConstraintSet.connect(R.id.id_tv_2, ConstraintSet.END, R.id.id_main, ConstraintSet.END, 0);
        //R.id.id_tv_1的右边与R.id.id_tv_2的左侧对齐
        applyConstraintSet.connect(R.id.id_tv_1, ConstraintSet.END, R.id.id_tv_2, ConstraintSet.START, 0);
        applyConstraintSet.connect(R.id.id_tv_2, ConstraintSet.START, R.id.id_tv_1, ConstraintSet.END, 0);
        //R.id.id_tv_2的右边与R.id.id_tv_3的左侧对齐
        applyConstraintSet.connect(R.id.id_tv_2, ConstraintSet.END, R.id.id_tv_3, ConstraintSet.START,0);
        applyConstraintSet.connect(R.id.id_tv_3, ConstraintSet.START, R.id.id_tv_2, ConstraintSet.END,0);
        applyConstraintSet.connect(R.id.id_tv_3, ConstraintSet.END, R.id.id_main, ConstraintSet.END,0);
        //设置ChainStyle
        applyConstraintSet.setHorizontalChainStyle(R.id.id_tv_1, ConstraintSet.CHAIN_PACKED);
        applyConstraintSet.constrainWidth(R.id.id_tv_1, ConstraintSet.WRAP_CONTENT);
        applyConstraintSet.constrainHeight(R.id.id_tv_2, ConstraintSet.WRAP_CONTENT);
        applyConstraintSet.constrainWidth(R.id.id_tv_2, ConstraintSet.WRAP_CONTENT);
        applyConstraintSet.constrainHeight(R.id.id_tv_2, ConstraintSet.WRAP_CONTENT);
        applyConstraintSet.constrainWidth(R.id.id_tv_3, ConstraintSet.WRAP_CONTENT);
        applyConstraintSet.constrainWidth(R.id.id_tv_3, ConstraintSet.WRAP_CONTENT);
        applyConstraintSet.applyTo(constraintLayout);

要实现三种不同的排列,只需要改变ChainStyle即可

//设置ChainStyle
applyConstraintSet.setHorizontalChainStyle(R.id.id_tv_1, ConstraintSet.CHAIN_PACKED);
applyConstraintSet.setHorizontalChainStyle(R.id.id_tv_1, ConstraintSet.CHAIN_SPREAD_INSIDE);
applyConstraintSet.setHorizontalChainStyle(R.id.id_tv_1, ConstraintSet.CHAIN_SPREAD);
6.实现两种layout的转换

如同最开始的gif动画,其实就是layout1切换到layout2,前提是layout1中view与layout2view id必须对应,多一个或者少一个都会报Exception:
在这里插入图片描述

首先我们准备两个Layout:
R.layout.activity_constraint_layout

<?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"
    android:id="@+id/id_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/id_image"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_margin="20dp"
        android:scaleType="fitStart"
        android:src="@drawable/about_bg"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/id_tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:text="@string/str_title"
        app:layout_constraintLeft_toRightOf="@+id/id_image"
        app:layout_constraintTop_toTopOf="@+id/id_image" />
    <TextView
        android:id="@+id/id_tv_content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp"
        android:layout_marginStart="12dp"
        android:maxLines="3"
        android:text="@string/str_content"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/id_image"
        app:layout_constraintTop_toBottomOf="@+id/id_tv_title" />
    <Button
        android:id="@+id/id_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:onClick="apply"
        android:text="apply"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" />
    <Button
        android:id="@+id/id_btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="reset"
        android:text="reset"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/id_btn" />
</android.support.constraint.ConstraintLayout>

R.layout.activity_constraint_layout2

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/id_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:scaleType="fitStart"
        android:src="@drawable/about_bg"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/id_tv_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="12dp"
        android:paddingBottom="4dp"
        android:paddingTop="4dp"
        android:text="@string/str_title"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/id_image" />
    <TextView
        android:id="@+id/id_tv_content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="12dp"
        android:layout_marginStart="12dp"
        android:layout_marginTop="6dp"
        android:text="@string/str_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/id_tv_title" />
    <Button
        android:id="@+id/id_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:onClick="apply"
        android:text="apply"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" />
    <Button
        android:id="@+id/id_btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="reset"
        android:text="reset"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/id_btn" />
</android.support.constraint.ConstraintLayout>

两个XML解析图为:

然后切换一下就可以了:

public class ConstraintLayoutActivity extends AppCompatActivity {
    private ConstraintLayout constraintLayout ;
    private ConstraintSet applyConstraintSet = new ConstraintSet();
    private ConstraintSet resetConstraintSet = new ConstraintSet();
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_constraint_layout);
        constraintLayout = findViewById(R.id.id_main);
        applyConstraintSet.clone(constraintLayout);
        resetConstraintSet.clone(this,R.layout.activity_constraint_layout2);
    public void apply(View view) {
        TransitionManager.beginDelayedTransition(constraintLayout);
        resetConstraintSet.applyTo(constraintLayout);
    public void reset(View view) {
        TransitionManager.beginDelayedTransition(constraintLayout);
        applyConstraintSet.applyTo(constraintLayout);

参考:
1.
http://www.uwanttolearn.com/android/constraint-layout-animations-dynamic-constraints-ui-java-hell/
2.https://github.com/OCNYang/Android-Animation-Set/tree/master/constraint-animation

作为一名从事Android的开发者,很多人最近都在和我吐槽Android是不是快要凉了?而在我看来这正是市场成熟的表现,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!GitHub地址09812)][外链图片转存中…(img-jL3Co7iA-1711325209812)][外链图片转存中…(img-z0xYWVQb-1711325209812)] 这几天心情不怎么好,加上上班的时候修改一堆的BUG,感觉整个人都不好了!但是我告诉自己不能这样的生活,只能把所有的情绪都放在文章中吧!希望能通过写文章让自己变得平静。什么事情都会过去的! 今天我们说点什么呢?ConstraintLayout之前在博客中讲过,当时只怪自己年少不懂事,竟不知道这东西的神奇?其实我觉得你也不知道!!!今天修改BUG百度的时候,居然看到ConstraintLayou... ConstraintLayout 动画的实现有两种方式实现,一种是 XML 方式实现,另外一种是Java,两者各有优点,下面就分别介绍两种实现方式,只要会 ConstraintLayout ,实现都非常简单。动画对字体、背景颜色、字体颜色、text、padding等都不生效,只对布局约束改变生效。当阅读这篇文章,我已经假设读者已经知道了 ConstraintLayout 的基本用法,如果不知道的请... 前言最近ConstrainLayout是Android中比较火的一个东西。ConstrainLayout可以使View层级扁平化,提升性能,支持任意的边框,其目的就是修复之前layout的一些短板。其实ConstrainLayout还有一个大多数人没有注意到的特性:可以利用Constrainlayout快速构建漂亮的动画效果。方法我这里假设已经你已经掌握了Constrainlayout基本知识(比... 前言最近ConstrainLayout是Android中比较火的一个东西。ConstrainLayout可以使View层级扁平化,提升性能,支持任意的边框,其目的就是修复之前layout的一些短板。其实ConstrainLayout还有一个大多数人没有注意到的特性:可以利用Constrainlayout快速构建漂亮的动画效果。方法我这里假设已经你已经掌握了Constrainlayout基本知识(比... 目录什么是ConstraintLayout简要介绍如何使用ConstraintLayout配置依赖基本属性用法示例居中偏移基线对齐实例GuidelineGroupBarrier如何利用ConstraintLayout创建动画基本思想动画效果总结 什么是ConstraintLayout ConstraintLayout名为约束布局,如它的名字所示,ConstrainLayout可以通过约束一个控件相对于另一个控件的位置来得到你想要的布局。这么一说,似乎RelativeLayout也能做到,但是Con 最近在无意中看到一篇关于ConstraintLayout的文章,文章着重介绍了最新的ConstraintLayout支持实现动画效果。于是我参照文章的内容,实现的动画效果如下: 是不是炫酷屌炸天!关键的是那么复杂的动画效果仅仅用几行代码!!!! 1.把我们的ConstaintLayout的版本是升级到1.0.0-beta4’compile 'com.android.sup 欧力给,已经学会创建,但好像没什么卵用。我们来看看刚刚自动生成的文件。】根标签有一个属性,表示所有未指定时间的动画的默认时间,默认为300毫秒。根标签 必须包含Transition标签,可以有多个Transition标签。Transition标签是用来指定动画的开始和结束状态、任何中间状态以及触发动画的动作,可以理解为一个Transition标签对应一个动画。同时,标签可以包含标签,这是可选的。标签主要为Transition标签提供起始和结束状态的位置和属性。而标签必须包含一个或多个Constraint。 介绍本系列我们已经介绍了ConstraintLayout的基本用法。学习到这里,相信你已经熟悉ConstraintLayout的基本使用了,如果你对它的用法还不了解,建议您先阅读我之前的文章。使用ConstraintLayout创建动画的基本思想是我们创建两个不同的布局,每个布局有其不同的约束,从而我们使用其动画框架来进行两种约束之间的切换。传统动画以往在我们创建简单动画时,通常我们会使用视图动画...