Android DeveloperAndroid笔记本Android开发学习

Android ConstraintLayout

2018-10-24  本文已影响6人  So_ProbuING

在升级Android Studio 2.3之后,发现再创建Activity生成的布局都是以ConstraintLayout作为根布局,浏览了一下Google官方力推的ConstraintLayout后,觉得这个布局很实用。

平台支持

com.android.support.constraint:constraint-layout:xxx版本号

基础使用

ContraintLayout 翻译成中文是约束布局,在整个使用中,对于组件的约束很明显。

ConstraintLayout定义

ConstraintLayout可以灵活控制子控件的位置和大小的新布局。这个布局可以实现布局最大程度的扁平化

为什么要使用ConstraintLayout

我们知道项目中的布局嵌套问题对我们的项目性能有着不小的威胁。布局能实现扁平化的话会让软件性能得到很大的提升。所以我们在开发中应当尽量避免布局嵌套现象

对比LinearLayout和RelativeLayout

在Android传统的布局 LinearLayout和RelativeLayout布局中,我们知道,在measure过程中 RelativeLayout是measure两次的。而LinearLayout是正常情况下只会measure一次,非正常情况下,在使用LinearLayout中的weight属性的控件做第二次measure。综合来看使用LinearLayout性能上来说比RelativeLayout好些。所以系统的decorview也就是使用的LinearLayout,上面是标题栏下面是内容ContentView。


效果图

我们想要实现一个左边是一个图片控件,右边是一个上下的标题

就是普通的item的布局,我们的布局文件是

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".basicfunc.home.view.AppHomeActivity">

    <TextView
        android:id="@+id/tv0"
        android:layout_width="140dp"
        android:layout_height="80dp"
        android:background="@android:color/holo_red_light"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@id/tv0"
        app:layout_constraintTop_toTopOf="@id/tv0"
        android:layout_marginLeft="8dp"
        android:text="主标题主标题主标题主标题主标题主标题主标题"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/tv1"
        app:layout_constraintLeft_toRightOf="@id/tv0"
        android:layout_marginLeft="8dp"

        android:text="副标题副标题副标题副标题副标题副标题"
        android:textSize="12sp" />

</android.support.constraint.ConstraintLayout>

上面的布局,我们看到了几个没有见过的属性,我们来介绍一下
首先是tv0:

app:layout_constraintLeft_toLeftOf = "@id/viewB"
app:layout_constraintLeft_toRightOf

即当前属性的左侧在谁的右侧,我们希望控件A在控件B的右侧时可以设置

app:layout_constraintLeft_toRightOf="@id/viewB"

类似的属性

    layout_constraintRight_toLeftOf
    layout_constraintRight_toRightOf
    layout_constraintTop_toTopOf
    layout_constraintTop_toBottomOf
    layout_constraintBottom_toTopOf
    layout_constraintBottom_toBottomOf
    layout_constraintBaseline_toBaselineOf

和Relative的差异

Relative

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"> <Button
        android:id="@+id/id_btn01"
        android:layout_width="100dp"
        android:text="Btn01"
        android:layout_height="wrap_content" /> <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/id_btn01"
        android:text="Btn02"
        android:layout_alignParentRight="true"
        /> </RelativeLayout>
RL效果

ConstraintLayout

layout_toRightOf="@id/id_btn01",layout_alignParentRight="true"

分别替换为:

app:layout_constraintLeft_toRightOf="@id/id_btn01",app:layout_constraintRight_toRightOf="parent"
ConstraintLayout效果

我们发现布局效果不一致

在当控件有自己设置的宽度,例如 wrap_content,固定值时,我们为控件添加的都是约束"Constrain",这个约束有点像作用力一样去挤压这个控件,但是不会改变控件的尺寸,很明显的RelativeLayout不是这样

但是,上面的这种情况下,如果我们使用约束 约束btn2在 btn1的同时 又与parent右侧对其,当两个约束同时生效的时候,btn02会居中。会造成这个作用力两端一样大。
这是为什么?如何能达到btn2将占据剩下的距离
当我们将btn2的宽度设置为0

这里我们明白了。在ContraintLayout中 0的意义:代表MATCH_CONSTRAINT
在ContraintLayout中已经不再支持MATCH_PARENT这个值了,可以通过MATCH_CONSTRAINT来实现效果

现在我们再来看看ContraintLayout强大的效果
我们在我们的item上再添加一个TextView 宽度为整个屏幕 长宽比为16:9
在布局中设置长宽比是非常难的,我们一般需要再代码中去计算。如果使用了ConstraintLayout布局中就可以支持

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".basicfunc.home.view.AppHomeActivity">
    <TextView
        android:id="@+id/banner"
        android:layout_width="0dp"
        android:layout_height="0dp" 
        android:background="@android:color/holo_green_light"
        android:text="banner"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintDimensionRatio="H,16:9"
        />
    <TextView
        android:id="@+id/tv0"
        android:layout_width="140dp"
        android:layout_height="80dp"
        android:background="@android:color/holo_red_light"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/banner"
        />
....
宽高比效果

这个宽高比还支持这样的写法:

app:layout_constraintDimensionRatio="W,16:6"
app:layout_constraintDimensionRatio="H,16:6"

增加tab

<TextView
    android:id="@+id/tab1"
    android:layout_width="0dp"
    android:layout_height="30dp"
    android:background="#f67"
    android:gravity="center"
    android:text="Tab1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/tab2" /> <TextView
    android:id="@+id/tab2"
    android:layout_width="0dp"
    android:layout_height="30dp"
    android:background="#A67"
    android:gravity="center"
    android:text="Tab2"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toRightOf="@id/tab1"
    app:layout_constraintRight_toLeftOf="@+id/tab3" /> <TextView
    android:id="@+id/tab3"
    android:layout_width="0dp"
    android:layout_height="30dp"
    android:background="#767"
    android:gravity="center"
    android:text="Tab3"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toRightOf="@id/tab2"
    app:layout_constraintRight_toRightOf="parent" />

tab

在这样的效果中 我们增加了3个TextView来冒充tab,横向的依赖 3个tab两两设置约束(即你在我们的左边 我再你的右边)
这种效果对于LinearLayout也能实现,但是ConstraintLayout也有设置权重weight的属性

app:layout_constraintHorizontal_weight

如果我们将权重设置成了2:1:1


图片.png

我们已经见过一种效果了,即按照weight等分,可以成为weighted chain。设置条件为:
chainStyle=”spread”,所有控件宽度设置为match_constraint,因为默认就是spread,所以我们没有显示设置。
其取值还可以为:

* packed
* spread_inside

1.spread + 宽度非0


图片.png

2.spread + 宽度为0 且通过weight控制分配比例(等分)
3.spread_inside+ 宽度非0


图片.png

4 packed+宽度非0


图片.png 官网解释图片

bias属性

再没有bias属性的时候,我们刚才说了 ConstraintLayout作用于控件两侧的力量是一样大的,我们可以通过bias设置偏向某个方向的作用力
这个属性可以用于约束之前,控制两侧的“拉力”

<android.support.constraint.ConstraintLayout 
    ...
    tools:context="com.zhy.constrantlayout_learn.MainActivity"> <TextView
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="#612"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.9"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.9" /> </....>

bias:表示水平设置两侧间隙比例为90%与10% 通过这个我们可以实现类似于margin的效果


20170917222509804.jpg

最后

由于好久没有看Android了,对于一些新特性(ps:现在可能都不叫新特性了)还是不是很了解,打算通过做一个项目来学习一下,在学习过程中由于水平太菜,参考了很多大神的博客,向大神致敬:
鸿洋大神:https://blog.csdn.net/lmj623565791/article/details/78011599
掘金专题:http://blog.coderclock.com/2017/04/09/android/android-constraintlayout/

上一篇下一篇

猜你喜欢

热点阅读