Android ConstraintLayout ConstraintSet动态布局

Posted 赵彦军

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ConstraintLayout ConstraintSet动态布局相关的知识,希望对你有一定的参考价值。

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120730533
本文出自【赵彦军的博客】

Android ConstraintLayout 约束布局详解

Android ConstraintLayout ConstraintSet动态布局

在传统布局方式中,如果要改变某个控件的位置,需要获取 LayoutParams , 后台修改属性值就行了。

但是在约束布局 ConstraintLayout 中,要改变控件的约束条件,需要用到 ConstraintSet 类。主要有 5 个步骤

5个步骤

  • 第一步:创建 ConstraintSet() 实例
 val set = ConstraintSet()
  • 第二步:需要复制一份父布局的约束,方法有三个如下
set.clone(constraintLayout: ConstraintLayout);
set.clone(set: ConstraintSet);
set.clone(context: Context, constraintLayoutId: Int);
  • 第三步:设置组件之间的约束了
set.connect(int startID, int startSide, int endID, int endSide) 
set.connect(int startID, int startSide, int endID, int endSide, int margin)
set.centerHorizontally(int viewId, int toView)
set.centerVertically(int viewId, int toView)
  • 第四步:设置一个动画,并且要求api版本为19及以上
TransitionManager.beginDelayedTransition(ViewGroup sceneRoot)
  • 第五步:apply一下使设置生效
set.applyTo(ConstraintLayout constraintLayout)

修改约束-修改控件约束条件

我们先写一个布局

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/view1"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="#f00"
        android:gravity="center"
        android:text="view1"
        android:textColor="#fff"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.5" />

    <TextView
        android:id="@+id/view2"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/black"
        android:gravity="center"
        android:text="view2"
        android:textColor="#fff"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.2"
        app:layout_constraintWidth_percent="0.2" />

</androidx.constraintlayout.widget.ConstraintLayout>

重新定义约束条件如下:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val rootLayout: ConstraintLayout = findViewById(R.id.root)
        val view1: View = findViewById(R.id.view1)
        val view2: View = findViewById(R.id.view2)
        
        view1.setOnClickListener {
            val set = ConstraintSet()
            set.clone(rootLayout)
            //view1,view2 顶部对齐
            set.connect(R.id.view1, ConstraintSet.TOP, R.id.view2, ConstraintSet.TOP)
            //view1左边对齐view2左边,距离20px
            set.connect(R.id.view1, ConstraintSet.START, R.id.view2, ConstraintSet.END, 10)

            //增加过渡动画,动画也可以不用加,但是效果比较生硬
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                TransitionManager.beginDelayedTransition(rootLayout)
            }
            set.applyTo(rootLayout)
        }

        view2.setOnClickListener {
            val set = ConstraintSet()
            set.clone(rootLayout)

            //在父布局中垂直居中显示
            set.centerVertically(R.id.view2, ConstraintSet.PARENT_ID)

            //增加过渡动画,动画也可以不用加,但是效果比较生硬
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                TransitionManager.beginDelayedTransition(rootLayout)
            }
            set.applyTo(rootLayout)
        }
    }
}

效果如下:

修改约束-布局切换


首先定义两个布局,第一个布局 activity_main.xml:是一行显示4个图标

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/view1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/weixin"
        app:layout_constraintEnd_toStartOf="@id/view2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/view2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/weibo"
        app:layout_constraintEnd_toStartOf="@id/view3"
        app:layout_constraintStart_toEndOf="@id/view1"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/view3"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/aqq1"
        app:layout_constraintEnd_toStartOf="@id/view4"
        app:layout_constraintStart_toEndOf="@id/view2"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/view4"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintStart_toEndOf="@id/view3"
        android:src="@drawable/dingding"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

第二个布局 activity_main2.xml:2行显示4个图标

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/view1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/weixin"
        app:layout_constraintEnd_toStartOf="@id/view2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/view2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/weibo"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/view1"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/view3"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/aqq1"
        app:layout_constraintEnd_toStartOf="@id/view4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/view1" />

    <ImageView
        android:id="@+id/view4"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/dingding"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/view3"
        app:layout_constraintTop_toTopOf="@id/view3" />


</androidx.constraintlayout.widget.ConstraintLayout>


通过代码切换两个视图:

package com.example.myapplication

import android.os.Build
import android.os.Bundle
import android.transition.TransitionManager
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val rootLayout: ConstraintLayout = findViewById(R.id.root)
        val view1: View = findViewById(R.id.view1)
        val view2: View = findViewById(R.id.view2)

        //1行切换到2行
        view1.setOnClickListener {
            val set = ConstraintSet()
            set.clone(this, R.layout.activity_main2)
            //增加过渡动画,动画也可以不用加,但是效果比较生硬
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                TransitionManager.beginDelayedTransition(rootLayout)
            }
            set.applyTo(rootLayout)
        }

        //2行切换到1行
        view2.setOnClickListener {
            val set = ConstraintSet()
            set.clone(this, R.layout.activity_main)
            //增加过渡动画,动画也可以不用加,但是效果比较生硬
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                TransitionManager.beginDelayedTransition(rootLayout)
            }
            set.applyTo(rootLayout)
        }
    }
}

以上是关于Android ConstraintLayout ConstraintSet动态布局的主要内容,如果未能解决你的问题,请参考以下文章

Android开发 - 掌握ConstraintLayout介绍

Android ConstraintLayout的基本使用

是否建议在 Android 的 ConstraintLayout 中使用 LinearLayout?

了解使用Android ConstraintLayout

Android错误膨胀类android.support.constraint.ConstraintLayout

Android ConstraintLayout