简书链接:android约束布局容器ConstraintLayout的初探 文章字数:2178,阅读全文大约需要8分钟 约束布局容器声明
1 2 3 4 5 6 7 8 9 10 11 12 <android.support.constraint.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" tools:context="qssq666.cn.constraintlayout.MainActivity"> </android.support.constraint.ConstraintLayout>
注意
容器里面的控件如果设置了左右约束,将不支持设置match_parent 改用0dp代替
代替属性Important: MATCH_PARENT is not supported for widgets contained in a ConstraintLayout, though similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to “parent”.`
Guideline控件在容器里面可以设置wrap_content容器里面的控件位置摆放介绍
左上对齐 让容器里面的某控件相对于约束布局容器 实际上做上不需要加上属性默认就是,哈哈哈
1 2 3 4 app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"
f和它左边对齐 比如parent是整个屏幕,就需要设置这个,如果设置的是lefttoright parent那么肯定是看不到了因为parent是整个屏幕。
1 layout_constraintLeft_toLeftOf
右下对齐 前提是别再设置toLeftOf和 toTopOf了
1 2 app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent"
居中对齐 所有属性 上下左右 都使用上即可.
1 2 3 4 app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"
手动操作实现上面效果,无图无真相..文字介绍太枯燥了, 选择控件将弹出4个圆圈 选择每一个圆圈往它那方靠近屏幕的方向拉去,如果没拉到屏幕变上 开发工具是不会产生控件的偏移动画的,而且松手又回来了, 那么全部拉好之后就是上面的代码效果,上下左右居中。
下一步学习 让一个控件和之前那个居中的控件的右边对齐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是居中的!" android:id="@+id/center_view" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:text="我不跟随父亲我长度够长,我右边始终和中间view右边对齐" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintRight_toRightOf="@+id/center_view" /> //看到的效果就是 第二个控件在顶部,但是始终右边和中间的右边对齐。 手动拉如何产生这个效果呢?选择第二个控件的右边方向的圆圈连接到中间view的右边的圆圈。
找规律 app:layout_constraintRight_toRightOf 也就是 我的右边和哪个空间的右边对齐呢?如果填写为parent那就是和父容器的右边对齐,因此这里懂了吧。
仿RelativeLayout的属性用法 @id代表某控件 让当前控件在某控件 右边layout_toRightOf =@idlayout_constraintLeft_toRightOf =@id
让当前控件在某控件 之下layout_below =@idapp:layout_constraintTop_toBottomOf= =@id手动拖控件方法 就是选择上面的某控件的底部圆圈连接 需要在他下面控件的上边圆圈
让当前控件和某控件底部对齐layout_alignBottom =@idlayout_constraintBottom_toBottomOf =@id
手动拖控件方法 就是选择参考物的某控件的底部圆圈连接和另外一个想和他底部对齐的view底部圆圈进行连接
让当前控件和父控件右边对齐layout_alignParentRight=”true” layout_constraintRight_toRightOf=”parent”
举一反三,不再多介绍了。
#仿LinearLayout权重
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <Button android:id="@+id/btn_0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0" android:text="Btn01" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="0dp" /> <Button android:id="@+id/btn_1" android:layout_width="0dp" android:layout_height="wrap_content" android:background="#f00" android:text="Btn02" app:layout_constraintLeft_toRightOf="@+id/btn_0" app:layout_constraintRight_toRightOf="parent" />
右边占据剩余的宽度。左边宽度就是包裹内容了, 需要右边父容器对齐又需要在左边容器的右边。 有时候只能用代码写,因为鼠标操作的话拦住了。
让空间水平铺满屏幕的属性 1 2 3 android:layout_width="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
保持宽高比 16:9 *这里宽度是16高度9 也代表 H,16:9为何英文意思是相反的我就不知道了。
1 2 3 4 5 app:layout_constraintDimensionRatio="16:9" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"
和下面这个一样
1 2 3 4 5 app:layout_constraintDimensionRatio="H,16:9" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"
如果改成W
1 2 3 4 5 app:layout_constraintDimensionRatio="W,16:9" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"
那么高度尺寸比宽度尺寸大。另外上面的left_toleft right_toright 都必须填写,否则就没法做到宽高比了,否则你写死高宽。另外务必把宽度和高度设置成这样 android:layout_width="0dp" android:layout_height="0dp"
否则不会生效。 而我们的PercentFrameLayout
在26已经不再推荐使用了.如果使用26的buildtool工具会提出现删除线。 那么让我们来怀恋一下百分比布局的16:9
1 2 3 4 app:layout_aspectRatio="177%" app:layout_widthPercent="100%" android:layout_height="0dp" android:layout_width="match_parent"
多按钮等分权重
app:layout_constraintHorizontal_weight="1"
是控制权重比例的不填写此参数的时候权重就是1
每一个控件的左边右边都要约束好,否则宽度还是原来自身的宽度,不会起作用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <Button android:id="@+id/btn_0" android:layout_width="0dp" android:layout_height="wrap_content" android:background="#f00" android:text="Btn01" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/btn_1" /> <Button android:id="@+id/btn_1" android:layout_width="0dp" android:layout_height="wrap_content" android:background="#0f0" android:text="Btn01" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toRightOf="@id/btn_0" app:layout_constraintRight_toLeftOf="@+id/btn_2" /> <Button android:id="@+id/btn_2" android:layout_width="0dp" android:layout_height="wrap_content" android:background="#00f" android:text="Btn01" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toRightOf="@id/btn_1" app:layout_constraintRight_toRightOf="parent" />
加上margin不受影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <Button android:id="@+id/btn_0" android:layout_width="0dp" android:layout_height="wrap_content" android:background="#f00" android:text="Btn01" android:layout_margin="10dp" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/btn_1" /> <Button android:id="@+id/btn_1" android:layout_width="0dp" android:layout_margin="10dp" android:layout_height="wrap_content" android:background="#0f0" android:text="Btn01" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toRightOf="@id/btn_0" app:layout_constraintRight_toLeftOf="@+id/btn_2" /> <Button android:id="@+id/btn_2" android:layout_width="0dp" android:layout_margin="10dp" android:layout_height="wrap_content" android:background="#00f" android:text="Btn01" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toRightOf="@id/btn_1" app:layout_constraintRight_toRightOf="parent" />
写死宽度调试权重样式 app:layout_constraintHorizontal_chainStyle|layout_constraintVertical_chainStyle=”spread|spread_inside|packed”
spread 必须配合width=0使用
spread_inside packed 是必须配合width height不等于0的时候使用
spread和不填写一样,因此意义不大
spread_inside 和英文意思一样 非写死宽度的剩余宽度分配中,平均分配左右两边 是靠边的,而packed是紧靠在一起,剩余的在整个控件之外,紧靠在一起。
我以为可以做到相交和不相交处的权重等分,结果然并卵,也没啥用哈。 参考代码1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <Button android:id="@+id/btn_0" android:layout_width="50dp" android:layout_height="wrap_content" android:background="#f00" android:text="Btn01" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/btn_1" /> <Button android:id="@+id/btn_1" android:layout_width="50dp" android:layout_height="wrap_content" android:background="#0f0" android:text="Btn01" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toRightOf="@id/btn_0" app:layout_constraintRight_toLeftOf="@+id/btn_2" /> <Button android:id="@+id/btn_2" android:layout_width="50dp" android:layout_height="wrap_content" android:background="#00f" android:text="Btn01" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_weight="1" app:layout_constraintLeft_toRightOf="@id/btn_1" app:layout_constraintRight_toRightOf="parent" />
约束 _bias的作用 这里注意把约束容器的高度设置为patch_parent不然app:layout_constraintVertical_bias就测试不出来了
1 2 3 4 5 6 app:layout_constraintVertical_bias="0.9" app:layout_constraintHorizontal_bias="0.9" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"
0 -1距离是控制x或者y方向的 的右边(Horizontal)或者底边(Vertical)的百分比距离,1则是完全到右边了。
如果不配合layout_constraintBottom_toBottomOf righttoright left toleft bottomtoleft就没法测试效果了哈。上面的东西如果没设置bias是居中的,设置之后就开始被拉扯。
bias的意思是偏向于
辅助线控件的用法 `android.support.constraint.Guideline
1 2 3 4 5 6 7 8 9 10 11 <android.support.constraint.Guideline android:id="@+id/guideline_w" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horzontal" app:layout_constraintGuide_begin="50dp" app:layout_constraintGuide_end="50dp" app:layout_constraintGuide_percent="0.5" />
主要属性有3个
1 2 3 4 android:orientation="horzontal" app:layout_constraintGuide_begin="50dp" app:layout_constraintGuide_end="50dp" app:layout_constraintGuide_percent="0.5"
如果设置了百分比那么begin end都没卵用了, 百分比在哪里 begin在哪里由方向控制,不再多叙述。
辅助线和我们安卓开发平时应到的隐藏控件做辅助完全雷同啊,我也是这么玩的有时候需求没法解决就弄一个隐藏的view,然后below它的下面。
辅助线控件不可见
还有一些属性没有使用介绍,本人边写边学了一个下午…眼睛都花了
杂项学习 tools:layout_editor_absoluteY 是干啥的? 它只是用来开发工具显示控制偏移用的,下面这个代码得意思是让当前控件距离上边51dp但是实际上运行就不是你看到的开发工具看到的预览效果了。
1 tools:layout_editor_absoluteY="51dp"
实际上什么约束都没有用上就会出现下面的提示 但是运行是正常的。 是因为垂直或者水平方向没有添加约束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 This view is not constrained vertically: at runtime it will jump to the left unless you add a vertical constraint less... (Ctrl+F1) The layout editor allows you to place widgets anywhere on the canvas, and it records the current position with designtime attributes (such aslayout_editor_absoluteX .) These attributes are **not** applied at runtime, so if you push your layout on a device, the widgets may appear in a different location than shown in the editor. To fix this, make sure a widget has both horizontal and vertical constraints by dragging from the edge connections. 此视图不受垂直约束:在运行时它将跳转到 向左,除非您添加了一个垂直约束… (Ctrl + F1) 布局编辑器允许您将小部件放置在画布上的任何位置, 它记录当前位置和设计时间的属性(如aslayout_editor_absolutex 。) 这些属性在运行时不***,所以如果你推你的 布局在设备上,小部件可能出现在不同的位置。 在编辑器中显示。要解决此问题,请确保小部件具有两个水平。 和从边缘连接拖动的垂直约束。
本人写布局发现存在的问题和无法实现的方案记录
水平排列布局 左边是头像 中间是 纵向的3行文字, 右边是一个关注按钮 ,左中右都是应该居中的。
左边头像 ,中间2 到3个 上下垂直排列 view 居中。右边按钮居中的结构, 上下view无法控制居中,有知道的大神求指导 。约束的情况无法控制
中间垂直排列的某个view 隐藏了也就无法做到类似自动堆在一起。所以线性布局等布局还是有很多存在的意义的。
约束布局无法完美解决所有布局,必要的时候还是要借助其他布局特别是线性布局。
对比 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data /> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="2dp" android:orientation="horizontal"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerview_menu" android:layout_width="100dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_height="match_parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintWidth_percent="0.3" /> <FrameLayout android:id="@+id/fragment_space_inner" android:layout_width="0dp" android:layout_height="match_parent" android:="@+id/recyclerview_menu" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/recyclerview_menu" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"> </FrameLayout> </androidx.constraintlayout.widget.ConstraintLayout> </layout> <!-- <?xml version="1.0" encoding="utf-8"?> <androidx.core.widget.NestedScrollView 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=".uipage.my.MyFragment"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="match_parent" app:divider="@drawable/divider" android:orientation="vertical" app:dividerPadding="1dp" app:showDividers="middle|beginning|end" > <LinearLayout android:id="@+id/btn_print_test" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="10dip" android:paddingLeft="5dip" android:paddingTop="10dip" > <ImageView android:layout_width="35dp" android:layout_height="35dp" android:scaleType="fitCenter" android:src="@drawable/ic_launcher_foreground" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="10dp" android:gravity="center" android:text="打印测试" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/ll_devanning_box" android:orientation="horizontal" android:paddingBottom="10dip" android:paddingLeft="5dip" android:paddingTop="10dip" > <ImageView android:layout_width="35dp" android:layout_height="35dp" android:scaleType="fitCenter" android:src="@drawable/ic_launcher_foreground" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="10dp" android:gravity="center" android:text="拆箱" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="10dip" android:paddingLeft="5dip" android:paddingTop="10dip" > <ImageView android:layout_width="35dp" android:layout_height="35dp" android:scaleType="fitCenter" android:src="@drawable/ic_launcher_foreground" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="10dp" android:gravity="center" android:text="Test" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="10dip" android:paddingLeft="5dip" android:paddingTop="10dip" > <ImageView android:layout_width="35dp" android:layout_height="35dp" android:scaleType="fitCenter" android:src="@drawable/ic_launcher_foreground" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="10dp" android:gravity="center" android:text="Test" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="10dip" android:paddingLeft="5dip" android:paddingTop="10dip" > <ImageView android:layout_width="35dp" android:layout_height="35dp" android:scaleType="fitCenter" android:src="@drawable/ic_launcher_foreground" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="10dp" android:gravity="center" android:text="Test" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="10dip" android:paddingLeft="5dip" android:paddingTop="10dip" > <ImageView android:layout_width="35dp" android:layout_height="35dp" android:scaleType="fitCenter" android:src="@drawable/ic_launcher_foreground" /> <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="10dp" android:gravity="center" android:text="Test" android:textColor="@color/black" android:textSize="15dip" /> </LinearLayout> </androidx.appcompat.widget.LinearLayoutCompat> </androidx.core.widget.NestedScrollView> -->
和百分比
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <?xml version="1.0" encoding="utf-8"?> <layout> <data /> <android.support.percent.PercentRelativeLayout 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:layout_marginTop="2dp" android:orientation="horizontal"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview_menu" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" app:layout_widthPercent="30%" /> <FrameLayout android:id="@+id/fragment_space_inner" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@+id/recyclerview_menu" > </FrameLayout> </android.support.percent.PercentRelativeLayout> </layout>
参考链接 http://blog.csdn.net/lmj623565791/article/details/78011599 http://www.jianshu.com/p/111b2fbd333e