在前面转场动画的文章有提到TransitionManager.beginDelayedTransition()
方法,这个方法的作用是:当View状态变化时,产生动画效果。
比如下图两个按钮,当点击底部按钮时,使顶部按钮的长度或者文字发生变化。
默认情况的效果如下:
但是如果加入代码:
TransitionManager.beginDelayedTransition(rootView);
之后,会有动画效果,动画效果如下:
看到以上的效果对比就知道TransitionManager.beginDelayedTransition()
方法的强大之处了,由此,引出本篇文章:在约束布局中实现约束动画。
ConstraintLayout,即约束布局,是当前Google最为推荐的一个布局方式,当存在多个View并且多个View存在约束关系时,当其中某个View某位置、偏移量状态发生变化时,其他View的状态也随之变化。
下面开始举例说明
【举例1】
当两个按钮具有约束时,改变其中一个View的margin
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button button_3;
private ConstraintLayout constraintLayout;
private ConstraintSet constraintSet = new ConstraintSet();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
constraintLayout = findViewById(R.id.rootView);
button_3 = findViewById(R.id.button_3);
button_3.setOnClickListener(this);
constraintSet.clone(constraintLayout);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.button_3:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
TransitionManager.beginDelayedTransition(constraintLayout);
}
constraintSet.setMargin(R.id.button_1,ConstraintSet.START,100);
constraintSet.applyTo(constraintLayout);
break;
}
}
}
activity_main.xml
效果如下:
【举例2】
将按钮水平居中
关键代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
TransitionManager.beginDelayedTransition(constraintLayout);
}
constraintSet.centerHorizontally(R.id.button_1, R.id.rootView);
constraintSet.centerHorizontally(R.id.button_2, R.id.rootView);
constraintSet.applyTo(constraintLayout);
效果如下:
【举例3】
改变View的宽度和高度
核心代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
TransitionManager.beginDelayedTransition(constraintLayout);
}
((Button)findViewById(R.id.button_1)).setTextSize(8);
constraintSet.constrainWidth(R.id.button_1, 100);
constraintSet.constrainWidth(R.id.button_2, 200);
constraintSet.constrainHeight(R.id.button_1, 100);
constraintSet.constrainHeight(R.id.button_2, 200);
constraintSet.applyTo(constraintLayout);
效果如下:
【举例4】
将两个随机位置的View重新摆放为水平居中
核心代码如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
TransitionManager.beginDelayedTransition(constraintLayout);
}
//清除button1的约束
constraintSet.clear(R.id.button_1);
//清除button2的约束
constraintSet.clear(R.id.button_2);
//设置button1和button1之间的约束
constraintSet.connect(R.id.button_2, ConstraintSet.LEFT, R.id.button_1, ConstraintSet.RIGHT, 0);
constraintSet.connect(R.id.button_1, ConstraintSet.RIGHT, R.id.button_2, ConstraintSet.LEFT, 0);
//由于两个按钮的约束重置了,所以需要重新设置宽高
constraintSet.constrainWidth(R.id.button_1,ConstraintSet.WRAP_CONTENT);
constraintSet.constrainWidth(R.id.button_2,ConstraintSet.WRAP_CONTENT);
constraintSet.constrainHeight(R.id.button_1,ConstraintSet.WRAP_CONTENT);
constraintSet.constrainHeight(R.id.button_2,ConstraintSet.WRAP_CONTENT);
//建立水平链式关系
constraintSet.addToHorizontalChain(R.id.guideline, R.id.button_1, R.id.button_2);
//垂直居中
constraintSet.centerVertically(R.id.button_1, R.id.rootView);
constraintSet.centerVertically(R.id.button_2, R.id.rootView);
constraintSet.applyTo(constraintLayout);
效果如下:
【举例5】
这里重点说明一下约束动画的另一种写法
首先,声明两个布局activity_main1.xml
和activity_main2.xml
activity_main1.xml
activity_main2.xml
两个布局的View ID是一样的,就是布局位置不一样,其中第一个布局为默认加载布局。
代码如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button button_3;
private ConstraintLayout constraintLayout;
private ConstraintSet constraintSet1 = new ConstraintSet();
private ConstraintSet constraintSet2 = new ConstraintSet();
private boolean isFirst = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
button_3 = findViewById(R.id.button_3);
button_3.setOnClickListener(this);
constraintLayout = findViewById(R.id.rootView);
constraintSet1.clone(constraintLayout);
constraintSet2.clone(this, R.layout.activity_main2);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.button_3:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
TransitionManager.beginDelayedTransition(constraintLayout);
}
if(isFirst){
constraintSet2.applyTo(constraintLayout);
}else{
constraintSet1.applyTo(constraintLayout);
}
isFirst = isFirst ? false : true;
break;
}
}
}
效果如下:
这个效果类似于转场动画的场景动画
,两个布局相当于两个场景
,两布局之间相同的View ID类似于共享元素
。
[本章完...]