Android动画<第十二篇>:ConstraintLayout动画

在前面转场动画的文章有提到TransitionManager.beginDelayedTransition()方法,这个方法的作用是:当View状态变化时,产生动画效果。

比如下图两个按钮,当点击底部按钮时,使顶部按钮的长度或者文字发生变化。

Android动画<第十二篇>:ConstraintLayout动画_第1张图片
图片.png

默认情况的效果如下:

Android动画<第十二篇>:ConstraintLayout动画_第2张图片
188.gif
Android动画<第十二篇>:ConstraintLayout动画_第3张图片
189.gif

但是如果加入代码:

TransitionManager.beginDelayedTransition(rootView);

之后,会有动画效果,动画效果如下:

Android动画<第十二篇>:ConstraintLayout动画_第4张图片
190.gif
Android动画<第十二篇>:ConstraintLayout动画_第5张图片
191.gif

看到以上的效果对比就知道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




    

效果如下:

Android动画<第十二篇>:ConstraintLayout动画_第6张图片
192.gif

【举例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);

效果如下:

Android动画<第十二篇>:ConstraintLayout动画_第7张图片
193.gif

【举例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);

效果如下:

Android动画<第十二篇>:ConstraintLayout动画_第8张图片
194.gif

【举例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);

效果如下:


Android动画<第十二篇>:ConstraintLayout动画_第9张图片
195.gif

【举例5】 这里重点说明一下约束动画的另一种写法

首先,声明两个布局activity_main1.xmlactivity_main2.xml

activity_main1.xml




    
Android动画<第十二篇>:ConstraintLayout动画_第10张图片
图片.png

activity_main2.xml




    
Android动画<第十二篇>:ConstraintLayout动画_第11张图片
图片.png

两个布局的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;
        }
    }
}

效果如下:

Android动画<第十二篇>:ConstraintLayout动画_第12张图片
196.gif

这个效果类似于转场动画的场景动画,两个布局相当于两个场景,两布局之间相同的View ID类似于共享元素

[本章完...]

你可能感兴趣的:(Android动画<第十二篇>:ConstraintLayout动画)