内容简介:本系列我们已经介绍了ConstraintLayout的基本用法。学习到这里,相信你已经熟悉ConstraintLayout的基本使用了,如果你对它的用法还不了解,建议您先阅读我之前的文章。使用ConstraintLayout创建动画的基本思想是我们创建两个不同的布局,每个布局有其不同的约束,从而我们使用其动画框架来进行两种约束之间的切换。以往在我们创建简单动画时,通常我们会使用
本系列我们已经介绍了ConstraintLayout的基本用法。学习到这里,相信你已经熟悉ConstraintLayout的基本使用了,如果你对它的用法还不了解,建议您先阅读我之前的文章。
使用ConstraintLayout创建动画的基本思想是我们创建两个不同的布局,每个布局有其不同的约束,从而我们使用其动画框架来进行两种约束之间的切换。
传统动画
以往在我们创建简单动画时,通常我们会使用
- 视图动画(View Animation)
- 帧动画(Drawable Animation)
- 属性动画(Property Animation)
这三种在我们制作简单动画时非常简单和方便,特别是当我们只对某个特定的View制作动画时。但是当我们需要制作复杂动画时,特别是整个页面多个View同时执行动画时,这几种方式就显得力不从心了,需要大量的工作。
当然还有一种方式就是使用转场动画框架(Transition Framework),通过共享元素(Shared Element)制作动画,这个后面我们也会提到。
ConstraintLayout动画
我们这里通过一个示例来说明ConstraintLayout动画的创建。
- 首先,我们创建第一个布局(activity_main.xml),它是是我们的初始布局。
-
效果:
-
代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<TextView
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" />
<TextView
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" />
<ImageView
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" />
</android.support.constraint.ConstraintLayout>
我们的初始布局创建完毕后,我们需要创建一个动画结束布局,让动画框架知道执行完动画后布局是什么样的。
- 创建动画结束布局(activity_main_detail.xml)。
- 效果:
- 代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<TextView
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"/>
<TextView
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" />
<ImageView
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.support.constraint.ConstraintLayout>
这个页面是我们执行动画结束后的样子。那么开始和结束的布局我们都有了,我们怎样执行动画,让两个布局之间进行过渡呢?
答案是通过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);
最终效果:
只需简单的几行代码,就可以实现复杂的动画了!当然本示例为了说明ConstraintLayout动画的创建方法,布局比较简单。
如果需要复杂布局的动画切换,这种方式的优势就非常明显。如果使用传统创建动画方法,则有可能需要大量的时间和代码来实现。
问题探讨
为什么需要创建两个布局文件?
可能有人认为创建两个布局文件不是一个好的方式,两个布局中存在重复的代码,这样好吗?
实际上可能并没有你想象的那么不好,创建两个布局文件的目的只是让动画框架知道不同的约束而已,然后将不同的约束应用在过渡动画中,你可以在布局中把与约束无关的属性去掉。
如果你实在不喜欢创建两个布局文件的话,当然也可以在代码中来描述不同的约束。显然这样会大大增加复杂度和代码量。
与使用共享元素动画(Shared Element)有什么区别?
使用共享元素动画当然也可以实现这样的效果,但是使用共享元素动画你也需要创建两个布局,而且关键的不同是:
使用ConstraintLayout执行动画时,动画前后的View是同一个View对象。
而使用共享元素动画时动画前后的View是两个不同的View对象!
系列总结
本篇是本系列博客 《掌握ConstraintLayout》 的最后一篇。通过本系列的学习,相信你已经掌握了使用ConstraintLayout的大部分功能。
在实际开发的过程中,使用ConstraintLayout会使开发速度有不少的提升,再结合我的另一个系列《使用Data Binding》,会大大减少开发Android时的工作量,达到事半功倍的效果,提升生产力!
谢谢你的支持!
如有更多疑问,请参考我的其它Android相关博客:我的博客地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 动画学数据结构:轻松掌握数组和字符串
- 掌握面向对象编程本质,彻底掌握OOP
- 【Android 动画】动画详解之属性动画(三)
- 【Android 动画】动画详解之属性动画(五)
- Flutter 动画全解析(动画四要素、动画组件、隐式动画组件原理等)
- 如何入门掌握Nginx?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Data Structures and Algorithms
Alfred V. Aho、Jeffrey D. Ullman、John E. Hopcroft / Addison Wesley / 1983-1-11 / USD 74.20
The authors' treatment of data structures in Data Structures and Algorithms is unified by an informal notion of "abstract data types," allowing readers to compare different implementations of the same......一起来看看 《Data Structures and Algorithms》 这本书的介绍吧!