ConstraintLayout动画入门

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

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

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

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

先从简单的来,先看一下XML布局:


<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解析图为:
ConstraintLayout动画入门_第1张图片

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_SPREAD ConstraintSet.CHAIN_SPREAD_INSIDE ConstraintSet.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:
ConstraintLayout动画入门_第2张图片

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


<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


<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解析图为:

ConstraintLayout动画入门_第3张图片 ConstraintLayout动画入门_第4张图片

然后切换一下就可以了:

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)