Android开发经验谈Android开发高级UI

约束布局ConstraintLayout使用详解

2020-04-26  本文已影响0人  waiwaaa

Android Studio 2.3起,官方的模板默认使用 ConstraintLayoutConstraintLayout 官方文档,之前项目中用的比较少,有些属性不是很熟练,做个笔记方便查找

相对定位的常用属性:

layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf

注意点:

  1. 对于一个view,使用布局必须要设置水平方向及垂直方向的定位属性,不然会报错。
  2. 设置同一方向设置,比如水平方向,仅设置constraintLeft则会为左对齐,仅设置constraintRight则会右对齐,两者都设置默认居中对齐。如果不想居中对齐,则需要设置属性layout_constraintHorizontal_bias范围为0~1,默认居中为0.5.
    layout_constraintVertical_bias 垂直偏移

两个TextView的高度不一致,但是又希望他们文本对齐,这个时候就可以使用layout_constraintBaseline_toBaselineOf

边距

常用margin ConstraintLayout的边距常用属性如下:

android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom

我们只有设置了相应的约束margin才有效,如设置了layout_constraintLeft_toLeftOf或者
layout_constraintLeft_toRightOflayout_marginLeft才会生效。

goneMargin

goneMargin主要用于约束的控件可见性被设置为gone的时候,使用的margin值是否有效,属性如下:

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

尺寸约束

控件的尺寸可以通过四种不同方式指定:

1. 使用指定的尺寸

2.使用wrap_content,让控件自己计算大小

当控件的高度或宽度为wrap_content时,可以使用下列属性来控制最大、最小的高度或宽度:
android:minWidth 最小的宽度
android:minHeight 最小的高度
android:maxWidth 最大的宽度
android:maxHeight 最大的高度
注意!当ConstraintLayout为1.1版本以下时,使用这些属性需要加上强制约束,如下所示:
app:constrainedWidth=”true”
app:constrainedHeight=”true”

3.使用 0dp (MATCH_CONSTRAINT)

官方不推荐在ConstraintLayout中使用match_parent,可以设置 0dp (MATCH_CONSTRAINT) 配合约束代替match_parent

4.宽高比

当宽或高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比

app:layout_constraintDimensionRatio="H,2:3"指的是 高:宽=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 宽:高=2:3

如果两个或以上控件通过下图的方式约束在一起,就可以认为是他们是一条链(图为横向的链,纵向同理)。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

    <TextView
            android:id="@+id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="text1"
            android:background="@color/colorAccent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@id/text2"
            app:layout_constraintHorizontal_chainStyle="spread"
            app:layout_constraintTop_toTopOf="parent" />

    <TextView
            android:id="@+id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="text2"
            android:background="@color/colorPrimary"
            app:layout_constraintStart_toEndOf="@id/text1"
            app:layout_constraintEnd_toStartOf="@id/text3"
            app:layout_constraintTop_toTopOf="parent" />
    <TextView
            android:id="@+id/text3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="text3"
            android:background="#921"
            app:layout_constraintStart_toEndOf="@id/text2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

layout_constraintHorizontal_chainStyle默认为spread,效果如图

spread

另外两个取值packed

packed

spread_inside

spread_inside

辅助工具

Guideline

Guildline是一条辅助线,帮助你完成布局但它不会显示在界面上。
Guildline的主要属性:
android:orientation :垂直vertical,水平horizontal
layout_constraintGuide_begin 指定位置距离开始
layout_constraintGuide_end 指定位置距离结束
layout_constraintGuide_percent 距离顶部的百分比(orientation = horizontal时则为距离左边)

Barrier

假设有3个控件ABC,C在AB的右边,但是AB的宽是不固定的,这个时候C无论约束在A的右边或者B的右边都不对。当出现这种情况可以用Barrier来解决。Barrier可以在多个控件的一侧建立一个屏障,如下所示:


Barrier
<?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:layout_width="match_parent"
        android:layout_height="match_parent">

    <TextView
            android:id="@+id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:padding="10dp"
            android:text="text1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    <TextView
            android:id="@+id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:padding="10dp"
            android:text="this is the text2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/text1" />


    <androidx.constraintlayout.widget.Barrier
            android:id="@+id/barrier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="right"
            app:constraint_referenced_ids="text1,text2" />

    <TextView
            android:id="@+id/text3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#872"
            android:padding="10dp"
            android:text="text3"
            app:layout_constraintLeft_toRightOf="@+id/barrier" />

</androidx.constraintlayout.widget.ConstraintLayout>

效果如下

Barrier.png
app:barrierDirection为屏障所在的位置,可设置的值有:bottomendleftrightstarttop
app:constraint_referenced_ids为屏障引用的控件,可设置多个,用“,”隔开

Group

Group可以把多个控件归为一组,方便隐藏或显示一组控件,举个例子:

<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="text1,text3" />

设置groupvisibilityinvisible,则text1与text3均不可见。

Placeholder

Placeholder指的是占位符,可以定义一个位置,当给Placeholder使用setContentId()设置另一个控件的id,使这个控件移动到占位符的位置了

<?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:layout_width="match_parent"
        android:layout_height="match_parent">

    <Button
            android:id="@+id/left_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="left_top"
            android:textColor="@android:color/white"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="clickview"
            />

    <Button
            android:id="@+id/right_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="right_top"
            android:textColor="@android:color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="clickview"/>

    <Button
            android:id="@+id/left_bot_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="left_bot"
            android:textColor="@android:color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:onClick="clickview"/>
    <Button
            android:id="@+id/right_bot_btn"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="right_bot"
            android:textColor="@android:color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:onClick="clickview"/>

    <androidx.constraintlayout.widget.Placeholder
            android:id="@+id/place_holder"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:background="#ffff0000"
            android:text="right"
            android:textColor="@android:color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

</androidx.constraintlayout.widget.ConstraintLayout>

在Activity中设置

placeholder=findViewById(R.id.place_holder);

public void clickview(View view){
        placeholder.setContentId(view.getId());
    }

实现点击四个角的那一个按钮,那么该按钮就会显示在正中间

上一篇下一篇

猜你喜欢

热点阅读