使用Kotlin的Android约束布局

时间:2020-02-23 14:28:50  来源:igfitidea点击:

在本教程中,我们将讨论Android ConstraintLayout属性。
我们将学习如何通过XML布局以及使用Kotlin以编程方式基于约束来定位视图。

什么是Android ConstraintLayout?

Android约束是带有附加功能的RelativeLayout。
引入它们是为了防止过多的嵌套布局。
他们弄平了布局。

约束布局的一些特征是:

  • 相对于另一个视图的侧面放置一个视图的侧面。

  • 约束集

  • 设置水平/垂直偏置

  • 将视图链接和分组在一起

  • 壁垒

  • 设置视图将在屏幕上占据的宽度或者高度的百分比。

  • 循环定位视图。

约束布局依赖性

请在build.gradle文件中添加以下依赖项,以获取约束布局支持。

implementation 'com.android.support.constraint:constraint-layout:1.1.2'

我们来看一些在Android应用中使用约束布局的示例。

相对于彼此定位视图

让我们将视图拖放到屏幕中央。

如您在上面的GIF中所看到的,"按钮"位于屏幕中央,每一侧都有对父视图的约束。

我们可以删除一个约束或者全部约束,如下所示。

十字按钮用于删除所有约束。
单击圆将删除该特定面的约束。

您可以拖动相同的圆以创建新约束。

让我们看一下上述设计的XML布局。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <Button
      android:id="@+id/button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:text="Button"
      app:layout_constraintStart_toEndOf="@+id/button2"
      app:layout_constraintTop_toBottomOf="@+id/button2" 

  <Button
      android:id="@+id/button2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:text="Button"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" 
</android.support.constraint.ConstraintLayout>

父级是指根视图。

彼此左右位置(顶部/左侧/底部/右侧)的XML属性列表如下。

我们也可以通过它们的基线来对齐两个视图。

让我们学习如何使用Kotlin以编程方式创建约束。

约束集

ConstraintSet实例被定义为以编程方式设置约束。

activity_main.xml在ConstraintLayout标记内不包含任何内容。
让我们看一下主要活动Kotlin代码。

package net.androidly.androidlyconstraintlayout

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.constraint.ConstraintLayout
import android.support.constraint.ConstraintSet
import android.widget.Button
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

  val ID_1 = 1
  val ID_2 = 2

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

      val button = Button(this)
      button.text = "Button"
      button.id = ID_1
      val lp = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT)
      button.layoutParams = lp
      constraintLayout.addView(button)

      val button2 = Button(this)

      button2.text = "Button2"
      button2.id = ID_2
      constraintLayout.addView(button2)

      val constraintSet = ConstraintSet()
      //Copy all the previous constraints present in the constraint layout.
      constraintSet.clone(constraintLayout)

      constraintSet.connect(ID_1, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
      constraintSet.connect(ID_1, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
      constraintSet.connect(ID_1, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT)
      constraintSet.connect(ID_1, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT)

      constraintSet.connect(ID_2, ConstraintSet.BOTTOM, ID_1, ConstraintSet.TOP)
      constraintSet.connect(ID_2, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT)
      constraintSet.connect(ID_2, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT)
      constraintSet.applyTo(constraintLayout)

  }
}

clone()函数用于复制约束布局中定义的所有先前约束。

在上面的代码中,我们将第一个按钮设置在布局的中心,第二个按钮位于其顶部。

connect()函数还有一个附加的第五个参数,用于余量值。

XML布局中的父级等效项为ConstraintSet.PARENT_ID。

水平和垂直偏差

设置偏差的属性为:" app:layout_constraintVertical_bias"和" app:layout_constraintHorizontal_bias"。

他们期望的值为0到1,默认值为0.5。

约束的链接和分组

链用于在水平或者垂直方向上均匀分布视图。

xml布局代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <Button
      android:id="@+id/button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Button"
      app:layout_constraintBottom_toTopOf="@+id/button5"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/button4" 

  <Button
      android:id="@+id/button4"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginBottom="8dp"
      android:text="Button"
      app:layout_constraintBottom_toTopOf="@+id/button"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintVertical_chainStyle="spread_inside" 

  <Button
      android:id="@+id/button5"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="8dp"
      android:text="Button"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/button" 
</android.support.constraint.ConstraintLayout>

链样式可以是以下类型。

  • spread
  • spread inside
  • packed
  • weighted

加权样式要求在每个视图上设置权重。
重量最大的视图占用最多的空间。

app:layout_constraintHorizontal_weight用于设置水平链中的权重。

组用于将一组视图的可见性一起切换。

将以下内部XML代码添加到先前定义的约束布局中。

<android.support.constraint.Group
            android:id="@+id/group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="invisible"
            app:constraint_referenced_ids="button4,button9" 

壁垒(Barrier)

障碍用于基于组中的最大视图在一组视图上创建虚拟分隔线或者准则。

该虚拟分隔线可以与其他子视图连接。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <TextView
      android:id="@+id/textView"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:text="TextView\nTextView\nTextView\nTextView\nTextView"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" 

  <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:text="TextView\nTextView\nTextView\nTextView\nTextView\nTextView\nTextView\nTextView\nTextView"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toEndOf="@+id/textView"
      app:layout_constraintTop_toTopOf="parent" 

  <android.support.constraint.Barrier
      android:id="@+id/barrier"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      app:barrierDirection="bottom"
      app:constraint_referenced_ids="textView, textView2" 

  <Button
      android:id="@+id/button7"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:text="Button"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="@+id/barrier" 

</android.support.constraint.ConstraintLayout>

ConstraintLayout百分比宽度和高度

约束布局支持宽度和高度的百分比,就像LinearLayout一样。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <TextView
      android:id="@+id/textView"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:text="TextView\nTextView\nTextView\nTextView\nTextView"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" 

  <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:text="TextView\nTextView\nTextView\nTextView\nTextView\nTextView\nTextView\nTextView\nTextView"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toEndOf="@+id/textView"
      app:layout_constraintTop_toTopOf="parent" 

  <android.support.constraint.Barrier
      android:id="@+id/barrier"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      app:barrierDirection="bottom"
      app:constraint_referenced_ids="textView, textView2"
      tools:layout_editor_absoluteY="331dp" 

  <Button
      android:id="@+id/button7"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:text="Button"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="@+id/barrier" 

</android.support.constraint.ConstraintLayout>

对于百分比宽度,您必须将按钮的宽度设置为0dp,反之亦然。

约束布局的圆形定位

我们可以将视图放置在彼此之间的径向距离和角度处。
app:layout_constraintCircle用于引用视图,该视图将作为圆的中心。

app:layout_constraintCircleRadius和app:layout_constraintCircleAngle用于设置距圆心的半径距离和视图的定位角度。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <TextView
      android:id="@+id/textView"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginEnd="8dp"
      android:layout_marginStart="8dp"
      android:text="Hello"
      android:textSize="18sp"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" 

  <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Hi"
      android:textSize="18sp"
      app:layout_constraintCircleRadius="100dp"
      app:layout_constraintCircleAngle="45"
      app:layout_constraintCircle="@+id/textView"

  <TextView
      android:id="@+id/textView3"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Another"
      android:textSize="18sp"
      app:layout_constraintCircleRadius="100dp"
      app:layout_constraintCircleAngle="135"
      app:layout_constraintCircle="@+id/textView"

</android.support.constraint.ConstraintLayout>