三三要成为安卓糕手
零:创建布局文件方式
1:创建步骤
ctrl + alt + 空格 设置根元素
2:处理老版本约束布局
在一些老的工程中,constrainlayout可能没有办法被直接使用,这里需要手动添加依赖
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
这里的版本很多,需要斟酌
这里的implementation libs.constraintlayout
点进去其实就是一个声明;
参数解释:group理解成组织标识;name是依赖库的具体名称;最后一个是版本引用。我们也可以自己去定义一个依赖声明,如下图中的test,并加以运用
文件已被改变是否以最新的为主,synchronized现在就同步
总结:扩展库、第三方库可以帮助我们更好的开发,但不是必备的
一:约束布局源代码
在安卓系统中提供了三种布局方式:LinearLayout(线性布局),RelativeLayout(相对布局),Constrainlayout(约束布局)官方推荐使用第三种布局方式
1:Relative所在位置
解释:<Android API 34, extension level 7 Platform> 是项目创建的时候就会导入进来的一个api,我们的RelativeLayout类就处于其中
2:Constraint所在位置
可以看到我们的约束布局是在第三方工具库中提供的
二:方位约束
1:控件拖拽
所有布局方式都支持控件拖拽,但ConstraintLayout对拖拽的支持最好,
拖拽后的空间只支持预览,在程序运行后,并不会真的实现
tools的用法,相当于预览作用,运行时不会在Android手机上显示
如果当前的控件没有约束条件,就会显示在(0,0)的位置;
两点定位:一般需要设置x轴和y轴的坐标的
2:方位的控制
默认有这句话,就可以添加一些xml的属性
textview控件的左边在父控件的左边
<TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="@+id/root" /><TextViewandroid:id="@+id/textView3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="textView"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent" /><TextViewandroid:id="@+id/textView4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="textView"app:layout_constraintBottom_toBottomOf="@+id/root"app:layout_constraintRight_toRightOf="parent" /><TextViewandroid:id="@+id/textView5"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView5"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" />
效果展示
同时设置四个方向,就会四马分尸666,究极拉扯,如textView5
注意
app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"
当阅读习惯都是从左往右时,可以等价替换
三:同级控件位置约束
理解清楚方位,就可以控制控件与控件之间的相对位置,写法都是非常灵活的
<TextViewandroid:id="@+id/textView6"android:layout_width="wrap_content"android:layout_height="100dp"android:background="@color/my_blue"android:text="TextView6"app:layout_constraintLeft_toRightOf="@+id/textView5"app:layout_constraintTop_toBottomOf="@+id/textView5" /><TextViewandroid:id="@+id/textView7"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView7"app:layout_constraintRight_toLeftOf="@+id/textView5"app:layout_constraintTop_toBottomOf="@+id/textView5" />
<TextViewandroid:id="@+id/textView8"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="TextView"app:layout_constraintBottom_toBottomOf="@+id/textView6"app:layout_constraintLeft_toRightOf="@+id/textView6"app:layout_constraintTop_toTopOf="@+id/textView6" />
处于中间位置
再玩个离谱的兄弟
<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/textView9"android:text="textView9"app:layout_constraintLeft_toLeftOf="@+id/textView6"app:layout_constraintRight_toRightOf="@id/textView6"app:layout_constraintTop_toBottomOf="@id/textView6"app:layout_constraintBottom_toBottomOf="@id/textView6"/>
这里其实是基于控件外部为基准,而非内部的文字
四:文本基准线约束
我们现在希望以当前文字100为底线对齐,而不是以控件的外围做对齐的
RelativeLayout都是基于当前控件大小进行调整的,constraintlayout可以实现这个场景
1:RelativeLayout对齐方式
(1)代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/root"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/tv_price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:background="@color/my_blue"android:text="100"android:textColor="@color/white"android:textSize="56sp" /><TextViewandroid:id="@+id/tv_label"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:layout_toRightOf="@+id/tv_price"android:background="@color/my_blue"android:text="$"android:textColor="@color/white"android:textSize="28sp" /></RelativeLayout>
(2)效果
RelativeLayout都是基于当前控件大小进行调整的,还是做不到嘛呜呜┭┮﹏┭┮
(3)重要代码分析
相对布局居中方式是centerInParent,约束布局是二/四马拉扯
2:Baseline
有方法
Baseline_toBaselineOf
Baseline_toTopOf 以此类推
(1)关联文本控件
翻译为基准线
<TextViewandroid:id="@+id/tv_price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/purple"android:text="100"android:textColor="@color/white"android:textSize="56sp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/tv_label"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/purple"app:layout_constraintLeft_toRightOf="@+id/tv_price"app:layout_constraintBottom_toBottomOf="@+id/tv_price"app:layout_constraintBaseline_toBaselineOf="@+id/tv_price"android:text="$"android:textColor="@color/white"android:textSize="28sp" />
控件和控件之间能很好的匹配文字底部对齐
(2)关联非文本控件
注意
- 当使用
toBaselineOf
关联非文本控件时,ConstraintLayout 会将其基线视为 顶部位置(即top
)。因此,对于非文本控件,****toBaselineOf
的效果等同于toTopOf
。
<TextViewandroid:id="@+id/tv_label2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/purple"app:layout_constraintLeft_toRightOf="@+id/image_wechat"app:layout_constraintBaseline_toBaselineOf="@+id/image_wechat"android:text="$"android:textColor="@color/white"android:textSize="28sp" /><ImageViewandroid:id="@+id/image_wechat"android:layout_width="100dp"android:layout_height="100dp"android:background="@color/my_blue"android:src="@drawable/icon_wechat"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"/>
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
五:角度约束
1:angle和radius
<TextViewandroid:id="@+id/tv_price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/purple"android:text="100"android:textColor="@color/white"android:textSize="56sp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/tv_label"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/purple"android:text="$"android:textColor="@color/white"android:textSize="28sp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintCircle="@id/tv_price"app:layout_constraintCircleAngle="45"app:layout_constraintCircleRadius="100dp"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintLeft_toLeftOf="parent" />
- Angle 角度45度 可以设置为0~360
- Radius 半径(可以理解成两个控件的中心距离)
尽管添加了xy坐标,但还是以角度约束为准
六:百分比偏移
1:bias
<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/purple"android:text="我是一个水平偏移和竖直偏移"android:textColor="@color/white"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintHorizontal_bias="0.1"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.2" />
总结:只有当两边一起拉扯的时候,偏移量才会生效,这里指的就是start和end都设置
可以给0~1的小数参数,默认值为0.5,就是不左不右,在中间;
app:layout_constraintHorizontal_bias="0.1" 水平
app:layout_constraintVertical_bias="0.1" 竖直
七:View的可见性
1:visibility
<ImageViewandroid:id="@+id/image_wechat"android:layout_width="100dp"android:layout_height="100dp"android:background="@color/my_blue"android:src="@drawable/icon_wechat"android:visibility="visible"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/tv_label"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/purple"android:text="$"android:textColor="@color/white"android:textSize="28sp"app:layout_constraintBottom_toTopOf="@id/image_wechat"app:layout_constraintRight_toRightOf="@id/image_wechat"app:layout_goneMarginTop="50dp"app:layout_goneMarginBottom="50dp" />
设置为gone属性就变成右边的图片的效果了
2:gone
所有的View都有visibility(可见性)属性
参数值 | 是否显示在界面上 | 是否占用布局空间 | 是否参与布局计算 | 动态设置代码(Java/Kotlin) |
---|---|---|---|---|
visible | ✅ 显示 | ✅ 占用 | ✅ 参与 | view.setVisibility(View.VISIBLE) |
invisible | ❌ 隐藏 | ✅ 占用 | ✅ 参与 | view.setVisibility(View.INVISIBLE) |
gone | ❌ 隐藏 | ❌ 不占用 | ❌ 不参与 | view.setVisibility(View.GON |
gone不占用空间就会变成一个点,invisible只是单纯看不见,但是最外层的轮廓还在
3:goneMarginTop
变成了一个点之后,此时我们的$符号由于依赖关系也受到了影响,有时候会让我们看不到控件
app:layout_constraintBottom_toTopOf="@id/image_wechat"app:layout_constraintRight_toRightOf="@id/image_wechat"app:layout_goneMarginRight="50dp"app:layout_goneMarginBottom="50dp" />
这四句代码非常关键
TextView的底部在image的上面,所以只能用远离底部边距(goneMarginBottom)表现出来的效果就是往上边移了
TextView的底部在image的右边,所以只能用远离右部边距(goneMarginRight),表现出来的效果就是往左边移了
提问:为什么要移动呢?
如果image变成一个点,在左下角,导致依赖image而设置位置的控件位置变化,那不就找不到了嘛~~over