简介
在Google IO大会中不仅仅带来了Android Studio 2.2预览版,同时带给我们一个依赖约束控件–ConstraintLayout。一种构建于弹性Constraints(约束)系统的新型Android Layout,最终你将会在Android Studio中编辑与构建一个相对复杂的Layout。简单来说,她是相对布局的升级版本,但是区别与相对布局更加强调约束。何为约束,即控件之间的关系。
来看一张google给出的一张案例效果:
运行官方示例
使用Git 克隆到本地或者直接下载zipconstraint-layout官方示例
git clone https://github.com/googlecodelabs/constraint-layout.git
运行示例代码:
打开Android Studio,选择 File>New>Import Project导入项目既可以。
初次尝试
在讲解原理和其他知识之前,我们先尝试下ConstraintLayout
1,首先在项目中添加依赖:
dependencies {
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha2'
}
注:如果build报错,请查看sdk是否下载了ConstraintLayout支持:
2,建立ConstraintLayout布局
<?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/lay_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/dog"
app:layout_constraintBottom_toBottomOf="@id/lay_root"
app:layout_constraintLeft_toLeftOf="@+id/lay_root"
app:layout_constraintRight_toRightOf="@+id/lay_root"
app:layout_constraintTop_toTopOf="@id/lay_root" />
</android.support.constraint.ConstraintLayout>
我们来看看新版的studio在工作区相对以前版本的变化
工作区
在工作区中有两种预览,一种设计预览,一种叫做蓝图的东西。两者可以辅助进行布局预览,非常不错。
这里要介绍下,在工作区的左上角的几个图标的作用。
眼睛图标:用来控制是否显示约束的东西。
磁铁图标:用来自动吸附的东西,就是说两个按钮放在一起的时候会自动按照一定的约束条件进行链接。
清理图标:用来清除所有的约束,当鼠标放倒一个控件上时也会有一个清理图标出现,点击可以清除当前选中的控件的约束。
灯泡图标:用来自动推断约束条件的东西,运用这个可以更加智能快速的完成布局。
约束
为了更好的理解约束,下面来看一些源于谷歌案例:
如上图:
简单来说约束可以帮助你按照某种相互关系进行布局,可以让控件对齐等等操作,在这里我们操作后面的按钮并链接到前一个按钮的右端,并且间隔56dp。哪么此时无论我移动按钮1到哪儿,按钮2都将在按钮1的右边并间距56dp。
如上图:在这个图中我们看见有3种不同的手柄。
调整手柄
拖动该手柄能帮助你调整整个控件的大小。
约束手柄
这个约束手柄位于控件的四边,在四边上有四个小圆点,拖动该圆点并指向另外的控件的一边,哪么可以让该控件对其到指向的控件。当然你可以设置margin来提供对应的间距。如果需要清理掉单个约束,点击该圆点即可。
基线手柄
该手柄仅仅出现在有文字的控件中使用,或者继承TextView的控件中使用,其作用是对齐两个控件的文字基线。
基线限制:
- 基线只能链接到另一个控件的基线。
- 基线也不能与手柄进行链接。
google使用案例
1.首先选择一个约束手柄,并按住鼠标拖动到另外一个控件的手柄原点上,当链接线变成绿色的时候松开鼠标即可创建一个约束。
2.添加图片控件,链接TextView控件的顶部手柄到ImageView底部手柄,并拖动一定间距。可以看出约束添加时文本控件自动吸附到了图片的底部。
3.拖动图片控件顶部手柄到根布局顶部。
4.最后我们同时添加图片左边与右边的约束使其居中对齐。
5.添加基线约束。
属性面板
首先我们在屏幕上添加一个图片控件,并添加四边约束到根布局,此时我们看见的界面是这样的:
在属性面板的上面部分是我们的检查员(Inspector),在这个视图中显示了当前选中的控件的约束情况。根据意思很好理解,这里就不详述了。
其他功能介绍
自动链接
还记得上面说到工作区的时候说的自动链接磁铁图标么?
首先我们启用该功能。然后新建界面并且拖动一个图片控件到中心部分,然后放开,此时会看见编辑器自动为我们添加了图片四边的约束。
自动推断
自动推断也是用来辅助用户创建控件约束的;其原理是综合控件之间的关系创建对应的约束条件。要测试自动推断,首先我们关闭自动链接功能,此时我们添加一些控件,控件的布局如下,因为我们关闭了自动链接,并且采用拖动关系进行创建,此时界面上控件之间是没有约束关系的。
使用ConstraintLayout示例
我们来看一下最终效果吧。
这种效果在机顶盒中是经常看到的,我们分析下我们使用普通的控件的实现:
- 界面左侧和右侧高度是总高的1/3,
- 下面宽度为3/12、2/12、2/12、2/12, 3/12;
- 中间大图宽高分别为:1/2、 2/3
那么我们很容易实现上面的布局效果:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:background="#F00"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="#00F"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:cardBackgroundColor="@color/colorAccent" />
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:cardBackgroundColor="#0F0" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="6"></LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="#00F"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:cardBackgroundColor="@color/colorAccent" />
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:cardBackgroundColor="#0F0" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#0F0"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="#00F"></LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#0FF"></LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#0F0"></LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="#0FF"></LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="#00F">
</LinearLayout>
</LinearLayout>
</LinearLayout>
那如果使用ConstraintLayout会如何呢?
<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/activity_constraint"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.huaye.odyandroidstore.constraint.ConstraintActivity">
<android.support.constraint.Guideline
android:id="@+id/g0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.25"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="0dp" />
<android.support.constraint.Guideline
android:id="@+id/g1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.41666666"
tools:layout_editor_absoluteX="247dp"
tools:layout_editor_absoluteY="0dp" />
<android.support.constraint.Guideline
android:id="@+id/g2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5833333"
tools:layout_editor_absoluteX="345dp"
tools:layout_editor_absoluteY="0dp" />
<android.support.constraint.Guideline
android:id="@+id/g3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.75"
tools:layout_editor_absoluteX="444dp"
tools:layout_editor_absoluteY="0dp" />
<android.support.constraint.Guideline
android:id="@+id/g4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3333333"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="120dp" />
<android.support.constraint.Guideline
android:id="@+id/g5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.6666667"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="239dp" />
<android.support.v7.widget.CardView
android:id="@+id/img1"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toTopOf="@+id/g4"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/g0"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.CardView
android:id="@+id/img2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toTopOf="@+id/g5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/g0"
app:layout_constraintTop_toTopOf="@+id/g4" />
<android.support.v7.widget.CardView
android:id="@+id/img3"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/g0"
app:layout_constraintTop_toTopOf="@+id/g5" />
<android.support.v7.widget.CardView
android:id="@+id/img4"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_marginEnd="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="8dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toTopOf="@+id/g5"
app:layout_constraintLeft_toLeftOf="@+id/g0"
app:layout_constraintRight_toLeftOf="@+id/g3"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.CardView
android:id="@+id/img5"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/g0"
app:layout_constraintRight_toLeftOf="@+id/g1"
app:layout_constraintTop_toTopOf="@+id/g5" />
<android.support.v7.widget.CardView
android:id="@+id/img6"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/g1"
app:layout_constraintRight_toLeftOf="@+id/g2"
app:layout_constraintTop_toTopOf="@+id/g5" />
<android.support.v7.widget.CardView
android:id="@+id/img7"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/g2"
app:layout_constraintRight_toLeftOf="@+id/g3"
app:layout_constraintTop_toTopOf="@+id/g5" />
<android.support.v7.widget.CardView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="8dp"
android:layout_marginStart="4dp"
android:layout_marginTop="8dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toTopOf="@+id/g4"
app:layout_constraintLeft_toLeftOf="@+id/g3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.CardView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="4dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="8dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toTopOf="@+id/g5"
app:layout_constraintLeft_toLeftOf="@+id/g3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/g4" />
<android.support.v7.widget.CardView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="4dp"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/g3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/g5"
android:layout_marginStart="4dp"
android:layout_marginLeft="4dp" />
</android.support.constraint.ConstraintLayout>
由于上面使用Constraints系统来构建,所以布局深度大大降低。
参考:http://www.jianshu.com/p/792d2682c538
google constraint-layout实例