介绍

本系列我们已经介绍了ConstraintLayout的基本用法。学习到这里,相信你已经熟悉ConstraintLayout的基本使用了,如果你对它的用法还不了解,建议您先阅读我之前的文章。

使用ConstraintLayout创建动画的基本思想是我们创建两个不同的布局,每个布局有其不同的约束,从而我们使用其动画框架来进行两种约束之间的切换。

传统动画

以往在我们创建简单动画时,通常我们会使用

视图动画(View Animation)

帧动画(Drawable Animation)

属性动画(Property Animation)

这三种在我们制作简单动画时非常简单和方便,特别是当我们只对某个特定的View制作动画时。但是当我们需要制作复杂动画时,特别是整个页面多个View同时执行动画时,这几种方式就显得力不从心了,需要大量的工作。

当然还有一种方式就是使用转场动画框架(Transition Framework),通过共享元素(Shared Element)制作动画,这个后面我们也会提到。

ConstraintLayout动画

我们这里通过一个示例来说明ConstraintLayout动画的创建。

首先,我们创建第一个布局(activity_main.xml),它是是我们的初始布局。

效果:

-w290

代码:

android:id="@+id/cl_root"

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">

android:id="@+id/tv_score"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="8dp"

android:text="评分:8.3分"

app:layout_constraintStart_toStartOf="@+id/tv_name"

app:layout_constraintTop_toBottomOf="@+id/tv_name" />

android:id="@+id/tv_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginStart="20dp"

android:layout_marginTop="8dp"

android:text="无敌破坏王2"

android:textColor="#282828"

android:textSize="20sp"

app:layout_constraintStart_toEndOf="@+id/iv_poster"

app:layout_constraintTop_toTopOf="@+id/iv_poster" />

android:id="@+id/iv_poster"

android:layout_width="120dp"

android:layout_height="160dp"

android:layout_marginStart="20dp"

android:layout_marginTop="20dp"

android:scaleType="centerCrop"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintTop_toTopOf="parent"

app:srcCompat="@mipmap/wreck_it_ralph" />

我们的初始布局创建完毕后,我们需要创建一个动画结束布局,让动画框架知道执行完动画后布局是什么样的。

创建动画结束布局(activity_main_detail.xml)。

效果:

-w289

代码:

android:id="@+id/cl_root"

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">

android:id="@+id/tv_score"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginStart="52dp"

android:text="评分:8.3分"

app:layout_constraintBottom_toBottomOf="@+id/tv_name"

app:layout_constraintStart_toEndOf="@+id/tv_name"

app:layout_constraintTop_toTopOf="@+id/tv_name"/>

android:id="@+id/tv_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginStart="20dp"

android:layout_marginTop="20dp"

android:text="无敌破坏王2"

android:textColor="#282828"

android:textSize="20sp"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintTop_toTopOf="parent" />

android:id="@+id/iv_poster"

android:layout_width="0dp"

android:layout_height="0dp"

android:layout_marginTop="65dp"

android:scaleType="centerCrop"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintTop_toTopOf="parent"

app:srcCompat="@mipmap/wreck_it_ralph" />

这个页面是我们执行动画结束后的样子。那么开始和结束的布局我们都有了,我们怎样执行动画,让两个布局之间进行过渡呢?

答案是通过Android的TransitionManager来执行。

使用TransitionManager来执行动画

代码(MainActivity.java)

package cn.examplecode.constraintlayoutdemo;

import android.support.constraint.ConstraintLayout;

import android.support.constraint.ConstraintSet;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.transition.TransitionManager;

public class MainActivity extends AppCompatActivity {

private ConstraintLayout mConstraintLayout;

private boolean mIsDetail;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mConstraintLayout = findViewById(R.id.cl_root);

ConstraintSet constraintSet1 = new ConstraintSet();

ConstraintSet constraintSet2 = new ConstraintSet();

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

constraintSet1.clone(mConstraintLayout);

findViewById(R.id.iv_poster).setOnClickListener(v -> {

TransitionManager.beginDelayedTransition(mConstraintLayout);

if (!mIsDetail) {

constraintSet2.applyTo(mConstraintLayout);

mIsDetail = true;

} else {

constraintSet1.applyTo(mConstraintLayout);

mIsDetail = false;

}

});

}

}

我们来解释以上代码。

首先我们发现使用了这个类ConstraintSet,它是一个约束集合,保存了布局上所有元素的约束,因为我们需要在两个布局之间执行动画,所以我们需要创建两个约束集合的对象。

ConstraintSet constraintSet1 = new ConstraintSet();

ConstraintSet constraintSet2 = new ConstraintSet();

创建完约束集对象后,我们需要设置每个约束集对应的约束:

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

constraintSet1.clone(mConstraintLayout);

这里我们将当前布局的约束应用到constraintSet1中,将目标布局的约束应用到constraintSet2中。

接下来我们执行动画:

TransitionManager.beginDelayedTransition(mConstraintLayout);

# 从constraintSet1过渡到constraintSet2

constraintSet2.applyTo(mConstraintLayout);

# 从constraintSet2过渡到constraintSet1

constraintSet1.applyTo(mConstraintLayout);

最终效果:

ezgif-5-34173ef48cf2

只需简单的几行代码,就可以实现复杂的动画了!当然本示例为了说明ConstraintLayout动画的创建方法,布局比较简单。

如果需要复杂布局的动画切换,这种方式的优势就非常明显。如果使用传统创建动画方法,则有可能需要大量的时间和代码来实现。

问题探讨

为什么需要创建两个布局文件?

可能有人认为创建两个布局文件不是一个好的方式,两个布局中存在重复的代码,这样好吗?

实际上可能并没有你想象的那么不好,创建两个布局文件的目的只是让动画框架知道不同的约束而已,然后将不同的约束应用在过渡动画中,你可以在布局中把与约束无关的属性去掉。

如果你实在不喜欢创建两个布局文件的话,当然也可以在代码中来描述不同的约束。显然这样会大大增加复杂度和代码量。

与使用共享元素动画(Shared Element)有什么区别?

使用共享元素动画当然也可以实现这样的效果,但是使用共享元素动画你也需要创建两个布局,而且关键的不同是:

使用ConstraintLayout执行动画时,动画前后的View是同一个View对象。

而使用共享元素动画时动画前后的View是两个不同的View对象!

系列总结

本篇是本系列博客《掌握ConstraintLayout》的最后一篇。通过本系列的学习,相信你已经掌握了使用ConstraintLayout的大部分功能。

在实际开发的过程中,使用ConstraintLayout会使开发速度有不少的提升,再结合我的另一个系列《使用Data Binding》,会大大减少开发Android时的工作量,达到事半功倍的效果,提升生产力!

谢谢你的支持!

如有更多疑问,请参考我的其它Android相关博客:我的博客地址

android.复杂动画实现,Android开发 - 掌握ConstraintLayout(十一)复杂动画!如此简单!...相关推荐

  1. 《C++游戏开发》笔记十一 平滑动画:不再颤抖的小雪花

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9430645 作者:七十一雾央 新浪微博:http:// ...

  2. Android IOS WebRTC 音视频开发总结(十一)-- stunturn部署

    本篇文章主要介绍webrtc里面的stun,turn服务的安装与配置(转载请说明出处: http://www.cnblogs.com/lingyunhu, RTC.Blacker) 说到STUN,TU ...

  3. 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)

    随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译者: ...

  4. Android IOS WebRTC 音视频开发总结

    Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下) RTC.Blacker 2016-09-13 11:18 阅读:132 评论:0   An ...

  5. Android IOS WebRTC 音视频开发

    转 自:http://www.cnblogs.com/lingyunhu/category/626157.html 作者:lingyunhu rtc.blacker@gmail.com 随笔分类 - ...

  6. Android开发 - 掌握ConstraintLayout(一)传统布局的问题

    在传统的Android开发中,页面布局占用了我们很多的开发时间,而且面对复杂页面的时候,传统的一些布局会显得非常复杂,每种布局都有特定的应用场景,我们通常需要各种布局结合起来使用来实现复杂的页面.随着 ...

  7. Android开发 - 掌握ConstraintLayout(四)创建基本约束

    上一篇我们介绍了编辑器的基本使用,本文我们介绍创建基本的约束. "约束"表示View之间的位置关系.当我们在ConstraintLayout布局中创建View时,如果我们没有添加任 ...

  8. android 自定义刷新控件,Android开发中MJRefresh自定义刷新动画效果

    有时候我们对自己开发的项目经常不满意,但是我们要达到自定义刷新动画的效果有一定的难度,别着急,下面爱站技术频道和大家分享Android开发中MJRefresh自定义刷新动画效果,一起来学习吧! [一] ...

  9. Android开发 - 掌握ConstraintLayout(七)辅助线(Guideline)

    了解过UI设计的同学都知道,在设计的时候,我们经常在界面上拖进一些辅助线来帮我们对齐UI元素,或者方便我们统一的页边距. 在ConstraintLayout的编辑器中,同样也支持这样的功能,我们可以创 ...

最新文章

  1. Python,OpenCV提取图片中的多个茄子种子轮廓,并按从左到右排序后显示
  2. ReSharper修改命名风格
  3. 阿里资深AI工程师教你逐个击破机器学习核心算法
  4. oracle的存储过程 替换,为什么在存储过程中,变量替换无法使用索引?
  5. NYOJ176 整数划分(二)
  6. 关于python import的sys.path路径问题
  7. php 编译记录文件,php-7.1编译记录
  8. 简单瀑布流-jquery实现
  9. 压缩感知重构算法——SP算法
  10. java applet 按钮_Java Applet语法简介
  11. 4k视频分辨率的码流_4k分辨率普通码率和蓝光1080p高码率视频,到底哪个体验好?...
  12. java微信学生考勤小程序前台vue和后台(考勤,请假,校园新闻,导出,地图等)(需要使用的软件)打包源码及安装视频+功能文档
  13. 【八种基本分析方法】
  14. an error occurred while creating opening the c++ browsing database 解决办法
  15. Gym - 101350E-Competitive Seagulls-博弈-思维
  16. 负数二进制转换十进制
  17. OpenGL 渲染点GL_POINTS
  18. wireshark怎么抓包、wireshark抓包详细图文教程
  19. Kali与编程:小白黑客是如何安装Centos8的?(下节更精彩)
  20. 期权 matlab vba,最全的期权定价VBA模板

热门文章

  1. 聊聊经常出现的优惠券系统
  2. EMV L1(7816)学习(Smart Cart智能卡)-1
  3. python3.7 buildroot numpy错误_遇到python3.7版本下pyinstaller打包无限出错,求大神指导...
  4. 【数据结构】二叉树——理论篇
  5. android高德地图webview的显示不出来,Android 使用webview遇到的问题及解决办法
  6. 怎样创建一个xcode插件 第2部分/3部分
  7. Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)(示例代码)
  8. Http Post注册QQ号码 分析流程图 更新时间20141206
  9. Ext JS的4.1.0的RC 1的发行说明
  10. day1 request的使用