Android ConstraintLayout

一、傳統(tǒng)界面布局

在安卓開發(fā)中,界面編程是一個很重要的部分,而很多時候?yàn)榱藢?shí)現(xiàn)好看的 ui 界面會用到很多層的布局來實(shí)現(xiàn),當(dāng)一個應(yīng)用的界面含有多個控件并且布局嵌套的層級大于三層時可能界面的渲染速度就會變慢,導(dǎo)致界面丟幀,這時界面加載起來就會很不流暢。極端情況下也會發(fā)生 ANR (Application Not Responding) 。因此一個優(yōu)秀的界面應(yīng)該盡量的去滿足以下兩點(diǎn)。

  • 布局嵌套的層級經(jīng)可能的少
  • 布局中的控件應(yīng)該盡可能的使用相對位置。
    使用相對位置可以在不用分辨率的設(shè)備中保持布局效果的一致性。

但是以上兩點(diǎn)往往是沖突的,降低嵌套層級的方式是使用 RelativeLayout, 而基于相對位置使用的是 LinearLayout。當(dāng)界面過于復(fù)雜時需要大量的 LinearLayout 保證控件的相對擺放,這樣會導(dǎo)致嵌套層級過多,如果使用 RelativeLayout控件之間的關(guān)系及其冗余,這時的界面可讀性差也難與修改。

二、ConstraintLayout布局

ConstraintLayout 即約束布局,在2016年的 Google I/O 大會上推出,可一定程度的替代掉 RelativeLayoutLinearLayout 接下來就開始了解一些簡單的用法。

  1. Hello World 的布局
<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

這個熟悉的代碼正是新版本的 Android Studio 新建項(xiàng)目時自動生成的布局文件,可以看到這個界面的根布局正是 ConstraintLayout。這個效果是讓 Hello World! 居中,其標(biāo)準(zhǔn)性模板如下

app:layout_constraint[ 本源位置 ]_to[ 目標(biāo)位置 ]="[ 目標(biāo)id ]"

  1. 指定約束
<?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"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/cancel_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="16dp"
        android:text="取消"
        app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
        app:layout_constraintStart_toStartOf="@id/constraintLayout" />

    <Button
        android:id="@+id/next_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="16dp"
        android:text="下一步"
        app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
        app:layout_constraintStart_toEndOf="@id/cancel_button" />

</android.support.constraint.ConstraintLayout>
  1. 設(shè)置比例
<?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"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="居中"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintEnd_toEndOf="@id/constraintLayout"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按比例偏移"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintEnd_toEndOf="@id/constraintLayout"
        app:layout_constraintHorizontal_bias="0.25"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintVertical_bias="0.25" />

</android.support.constraint.ConstraintLayout>
  1. 引導(dǎo)線布局
<?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">

    <android.support.constraint.Guideline
        android:id="@+id/guideLine"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="72dp"
        tools:layout_editor_absoluteX="72dp"
        tools:layout_editor_absoluteY="0dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="向上"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintStart_toStartOf="@id/guideLine"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintVertical_bias="0.25"
        tools:layout_editor_absoluteX="72dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="向下"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintStart_toStartOf="@id/guideLine"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintVertical_bias="0.75"
        tools:layout_editor_absoluteX="72dp" />

</android.support.constraint.ConstraintLayout>
  1. 布局填充
<?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"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/small"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="自適應(yīng)大小"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"
        app:layout_constraintTop_toTopOf="@id/constraintLayout" />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="取最寬的寬度"
        app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
        app:layout_constraintEnd_toEndOf="@id/constraintLayout"
        app:layout_constraintStart_toEndOf="@id/small"
        app:layout_constraintTop_toTopOf="@id/constraintLayout" />

</android.support.constraint.ConstraintLayout>
  1. 控件寬高比
<?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"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="@color/colorAccent"
        android:src="@mipmap/home_ban"
        app:layout_constraintDimensionRatio="16:9"
        app:layout_constraintLeft_toLeftOf="@+id/constraintLayout"
        app:layout_constraintRight_toRightOf="@+id/constraintLayout"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout" />

    <ImageView
        android:layout_width="200dp"
        android:layout_height="0dp"
        android:background="@color/colorAccent"
        android:contentDescription="@null"
        android:src="@mipmap/home_ban"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintDimensionRatio="4:3"
        app:layout_constraintLeft_toLeftOf="@+id/constraintLayout"
        app:layout_constraintRight_toRightOf="@+id/constraintLayout" />

</android.support.constraint.ConstraintLayout>
  1. 圓形定位
    這個用法簡直是完美的解決了消息列表里使用圓形頭像時右上角的未讀消息的點(diǎn)。
<?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"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/pic"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:src="@mipmap/login_sel_rel"
        app:layout_constraintCircle="@+id/image"
        app:layout_constraintCircleAngle="45"
        app:layout_constraintCircleRadius="70dp" />

</android.support.constraint.ConstraintLayout>

參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容