三三要成為安卓糕手
零:創建布局文件方式
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