Constraintlayout 新特性:Barrier、Group、Layer、Flow、ImageFilterView等


1.官方文檔

  https://developer.android.com/reference/androidx/constraintlayout/classes

  android系統中定義了一系列類,輔助ConstraintLayout 完成較復雜功能,如定邊界線、分組、分層、排列等等。它們大多數都是直接繼承ConstraintHelper,間接繼承View,它們大多數都是不不完整的view.

  • 不繪制onDraw為空
  • 默認大小為0(mUseViewMeasure默認為fasle,自定義的時候可改)
  • 無事件
  • Layer、Flow有些例外

   

 簡介如下:

基類 功能
ConstraintLayout

View

ViewGroup
ConstraintLayout 基本介紹,包含位置、大小等約束。
Group

 View

ConstraintHelper

This class controls the visibility of a set of referenced widgets.

用來把多個view約定為同一分組,通過控制Group對象的可見性,能同時控制組內多個view的可見性。

Layer  View

ConstraintHelper

 
Barrier   View

ConstraintHelper

A Barrier references multiple widgets as input, and creates a virtual guideline based on the

most extreme widget on the specified side. 

Guideline  View Utility class representing a Guideline helper object for ConstraintLayout
Flow
View

ConstraintHelper

VirtualLayout

 
Flow virtual layout. 
ImageFilterButton

ImageView

ImageButton

 AppCompatImageButton

An ImageButton that can display, combine and filter images. 
ImageFilterView

ImageView

AppCompatImageView

An ImageView that can display, combine and filter images. 
MockView View  A view that is useful for prototyping layouts. 
MotionLayout  ConstraintLayout A subclass of ConstraintLayout for building animations. 

 

2.實用尺寸約束

2.1 尺寸的計算方式

  • Fixed                        固定大小
  • Wrap Content          自適應大小
  • Match Constraints   取最大可用值
  • 寬/高 比例約束         一個方向為Match Constraints,另一個方向由比值計算

  在未限定 寬/高比約束 情況時,點下圖中箭頭指的線就可以設置寬、高的計算模式。

               

        圖1. Fixed                  圖2. Wrap Content                圖3. Match Constraints約束

2.2 layout_goneMarginStart

  當左邊依賴的view為GONE時,這個邊距依然有效,不會向左移動。

2.3 layout_constraintWidth_min

僅當 Match Constraints 時有意義,用它指定一個最小寬度,它可取的值如下:

  • dp 
    1     <TextView
    2         android:layout_width="0dp"
    3         android:layout_height="48dp"
    4         app:layout_constraintWidth_min="16dp"
    5         app:layout_constraintEnd_toEndOf="parent"
    6         app:layout_constraintStart_toStartOf="parent"
    7         app:layout_constraintWidth_percent="0.00001"
    8         .../>
  • "wrap",此時和 android:layout_width="wrap_content" 一樣
    1     <TextView
    2         android:layout_width="0dp"
    3         android:layout_height="48dp"
    4         app:layout_constraintWidth_min="wrap"
    5         app:layout_constraintWidth_percent="0.0000001"
    6         app:layout_constraintEnd_toEndOf="parent"
    7         app:layout_constraintStart_toStartOf="parent"
    8         />

其它事項

  1. 當 android:layout_width="wrap_content" 時使用android:minWidth,這時layout_constraintWidth_min無效
  2. app:layout_constraintWidth_max 與它同理

2.4 app:layout_constraintWidth_default

  僅當約束為Match Constraints 時,它有意義,可取值的如下:

  • percent             按百分比計算大小
  • wrap                 在限定的范圍內自適應大小,內容不保證能完全顯示。
  • spread (默認)    取可用最大值

其中 app:layout_constraintWidth_default="wrap"  與  android:layout_width="wrap_content" 的對比如下圖:

    

 1     <TextView
 2         android:layout_width="0dp"
 3         android:layout_height="24dp"
 4         android:text="width default wrap faasdfasdfasdfasdfasdfasdf"
 5         app:layout_constraintEnd_toEndOf="@+id/ratioView4"
 6         app:layout_constraintStart_toStartOf="@+id/ratioView4"
 7         app:layout_constraintWidth_default="wrap" 
 8         ... />
 9 
10     <TextView
11         ...
12         android:layout_width="wrap_content"
13         android:layout_height="24dp"
14         android:text="layout_width = wrap_content faasdfasdfasdfasdfasdfasdf"
15         app:layout_constraintEnd_toEndOf="@+id/ratioView4"
16         app:layout_constraintStart_toStartOf="@+id/ratioView4"
17         ... />

2.5 app:layout_constraintWidth_percent

  僅當約束為Match Constraints 時,它有意義,約定寬度是按照百分比計算,它的值是浮點數,表示百分比,如

1   <TextView
2         android:layout_width="0dp"
3         app:layout_constraintWidth_percent="0.2" .../>

2.6 app:layout_constraintDimensionRatio

 當寬、高以 Match Constraints 方式計算時,此屬性約定寬高按比值計算, 比值形式如下:

  • "浮點數值
    app:layout_constraintDimensionRatio="1.5"
  • "寬:高"
    app:layout_constraintDimensionRatio="3:1"
  • H,浮點數值” 或者 "W,浮點數值"
    app:layout_constraintDimensionRatio="W,2.5"
    W表示寬度通過比值計算得來,H表示高度通過比值計算得來
  • "H,寬:高"  或者 “W,寬:高” 
    app:layout_constraintDimensionRatio="W,2.5:1"

     W與H的含義與上方一樣

其它事項

  1. W,H可以小寫,
  2. 雖然是字符串,下面的都是錯的
    app:layout_constraintDimensionRatio="H,1.2:3:1"
    app:layout_constraintDimensionRatio="2:1a"
    app:layout_constraintDimensionRatio="world 2:1"
    app:layout_constraintDimensionRatio="w,2 ,h,1"

    等等

 

3.實用位置約束

3.1 角度對齊 

  按角度對齊控件,layout_constraintCircle、layout_constraintCircleRadius、layout_constraintCircleAngle 合在一起使用

    <TextView
        android:id="@+id/pivot" .../>

    <TextView
        app:layout_constraintCircle="@+id/pivot"
        app:layout_constraintCircleAngle="60"
        app:layout_constraintCircleRadius="48dp"
        ... />

  layout_constraintCircleAngle 取值是 0-360 ,順時針。

官方圖解如下:

  

3.2 鏈式對齊

  多個控件組成一個鏈,app:layout_constraintVertical_chainStyle 和app:layout_constraintVertical_chainStyle 可指定它們之間的排列方式,可取的值有

  • spread 默認 ,均勻分布
  • spread_inside ,首尾圖固定在鏈兩端,中間的均勻分布
  • packed 緊密向中心排列在一起

3.4 GuideLine

  輔助類,相關屬性

  • android:orientation="horizontal" 指定方向
  • app:layout_constraintGuide_percent="0.5" 百分比
  • app:layout_constraintGuide_begin="32dp" 
  • app:layout_constraintGuide_end="32dp"    

   其中 layout_constraintGuide_percent和app:layout_constraintGuide_begin 等 都是相對根布局的,示例如下:

1         <androidx.constraintlayout.widget.Guideline
2             android:id="@+id/center_line"
3             android:layout_width="wrap_content"
4             android:layout_height="wrap_content"
5             app:layout_constraintGuide_percent="0.50"
6             android:orientation="horizontal" />

3.3 Barrier

  給一組控件的最外邊添加一條隱藏的邊界線, 並且自己適應哪個控件的外邊是最外邊。其它控件可依賴這條線。

  官方圖示:

  

  示例:

1     <androidx.constraintlayout.widget.Barrier
2         android:layout_width="wrap_content"
3         android:layout_height="wrap_content"
4         app:barrierDirection="end"
5         app:barrierAllowsGoneWidgets="true"
6         app:constraint_referenced_ids="barrier1,barrier2,barrier3"
7         />

  app:barrierDirection="end" ,邊界線的方位,取值:start end,top,bottom,left,right

  app:constraint_referenced_tags="tag1,tag2" ,值是view的tag

  app:constraint_referenced_ids="barrierView1,barrierView2,barrierView3",值只能是view的id,不能是group,layer,barrier等id

  app:barrierAllowsGoneWidgets="true" ,這個屬性的原文如下

If the barrier references GONE widgets, the default behavior is to create a barrier on the resolved position of the GONE widget. 
If you do not want to have the barrier take GONE widgets into account, you can change this by setting the attribute
barrierAllowsGoneWidgets to false (default being true).

  並沒有看到true和false區別

  

  代碼如下:

1     <androidx.constraintlayout.widget.Barrier
2         ...
3         android:id="@+id/barrier1"
4         app:barrierDirection="end"
5         app:barrierAllowsGoneWidgets="false"
6         app:constraint_referenced_ids="barrierView1,barrierView2,barrierView3"
7         />

4.Group

4.1 簡介

  • 把多個view在約定為同一分組,通過控制Group對象的可見性,能同時控制組內多個view的可見性,不用分別操作每個view對象。
  • 它是View的子類,但在界面中不顯示,onDraw方法為空,顏色、事件等無意義。
  • 寬高在layout中不能省略。
  • 同一個view可加入到多個組中,該view的可見性由最后操作的那個組對象決定。

4.2 示例

  

  • group1 對象 包含:view1,view2,view3,view4,這幾個view,對它操作同時影響組內view
  • goup2 對象同理
  • view2,view3,view4同時在goup1,group2中,假設代碼中有分別對group1,group2可見性的操作,那么最后一個操作決定它們3個的可見性。

  代碼

 1     <TextView
 2         android:id="@+id/groupView1"
 3         android:text="View1"
 4         app:layout_constraintTag="view1".../>
 5 
 6     <TextView
 7         android:id="@+id/groupView2"
 8         android:text="View2"
 9         app:layout_constraintTag="view2"... />
10 
11     <TextView
12         android:id="@+id/groupView3"
13         android:text="View3"
14         app:layout_constraintTag="view3"... />
15 
16     <TextView
17         android:id="@+id/groupView4"
18         android:text="View4"
19         app:layout_constraintTag="view4" .../>
20 
21     <androidx.constraintlayout.widget.Group
22         android:id="@+id/group1"
23         android:layout_width="match_parent"
24         android:layout_height="48dp"
25         app:constraint_referenced_ids="groupView1,groupView2,groupView3,groupView4"
26         ... />
  • group 通過 app:constraint_referenced_ids 指定view的Id來分組
  • 也可以通過 constraint_referenced_tags 來分組(這時要求控件要使用app:layout_constraintTag聲明一個tag)
        app:constraint_referenced_tags="view1,view2,view3,view4"
  • 同組內重復的控件id或者tag只算一個,且沒有順序要求
  • id列表的只能基本它控件的id,layer、group、barrier、flow等不可以,tag同理。

  按鈕的事件,操作一個group對象就可以,不用分別操作4個對象。

1     private fun onGroup1BtnChanged(btn : CompoundButton, isChecked : Boolean){
2         binding.group1.visibility = if (isChecked) View.VISIBLE else View.INVISIBLE
3     }

5.Layer

  把一些控件組合在一起,當作一個圖層,該圖層自動計算邊界,也是View的子類,但是功能不是完整的。

5.1 示例

  

 1     <androidx.constraintlayout.helper.widget.Layer
 2         android:id="@+id/layer1"
 3         android:layout_width="match_parent"
 4         android:layout_height="match_parent"
 5         android:layout_marginTop="32dp"
 6         android:padding="8dp"
 7         android:visibility="visible"
 8         app:constraint_referenced_ids="layerView1,layerView2,layerView3,layerView4,layerView5"
 9         app:layout_constraintEnd_toEndOf="parent"
10         app:layout_constraintStart_toStartOf="parent"
11         app:layout_constraintTop_toBottomOf="@+id/textView4" />
 1 <androidx.constraintlayout.helper.widget.Layer
 2         android:id="@+id/layer2"
 3         android:layout_width="match_parent"
 4         android:layout_height="0dp"
 5         android:elevation="48dp"
 6         app:layout_constraintDimensionRatio="H,16:9"
 7         app:layout_goneMarginTop="32dp"
 8         app:constraint_referenced_ids="layerView2,layerView7,layerView6,layerView7"
 9         app:layout_constraintEnd_toEndOf="parent"
10         app:layout_constraintStart_toStartOf="parent"
11         app:layout_constraintTop_toBottomOf="@+id/layerView7" />

5.2 支持的操作

  • 設置背景色
  • 支持elevation屬性
  • 設置可見性
  • 支持補間動畫(alpha 是layer1動,scale,rotation,transaction是其中的每個控件同時動)
  • 多個圖層同時包含同一個控件
  • 圖層本身支持事
  • 支持padding、不支持margin、不支持大小

6.Flow

  把一組控件按添加的流順序一個接在一個后面,有橫向、豎向兩個方向,它是一個View但是比其它輔助類有更多的功能。

6.1 示例

  

flow1 代碼:

 1     <androidx.constraintlayout.helper.widget.Flow
 2         android:id="@+id/flow1"
 3         android:layout_width="0dp"
 4         android:layout_height="0dp"
 5         android:layout_marginStart="8dp"
 6         android:layout_marginLeft="8dp"
 7         android:layout_marginTop="12dp"
 8         android:layout_marginEnd="8dp"
 9         android:layout_marginRight="8dp"
10         android:background="#fff8f8f8"
11         android:orientation="horizontal"
12         android:padding="8dp"
13         android:visibility="visible"
14         app:flow_wrapMode="none"
15         app:constraint_referenced_ids="flowView1,flowView2,flowView3,flowView4,flowView5,flowView6"
16         app:flow_horizontalGap="8dp"
17         app:flow_horizontalBias="0.5"
18         app:flow_horizontalStyle="packed"
19         app:layout_constraintDimensionRatio="h,2:1"
20         app:layout_constraintEnd_toEndOf="parent"
21         app:layout_constraintStart_toStartOf="parent"
22         app:layout_constraintTop_toBottomOf="@+id/flowTitle" />

flow2 代碼:

 1 <androidx.constraintlayout.helper.widget.Flow
 2         android:id="@+id/flow2"
 3         android:layout_width="0dp"
 4         android:layout_height="0dp"
 5         android:layout_marginStart="8dp"
 6         android:layout_marginLeft="8dp"
 7         android:layout_marginTop="32dp"
 8         android:layout_marginEnd="8dp"
 9         android:layout_marginRight="8dp"
10         android:background="#f8f8f8"
11         android:padding="16dp"
12         android:visibility="visible"
13         android:orientation="vertical"
14         app:constraint_referenced_ids="flowView14,flowView13,flowView7,flowView8,flowView9,flowView10,flowView11,flowView12,flowView15,flowView16"
15         app:flow_horizontalAlign="start"
16         app:flow_horizontalGap="8dp"
17         app:flow_maxElementsWrap="4"
18         app:flow_verticalGap="16dp"
19         app:flow_verticalStyle="packed"
20         app:flow_wrapMode="aligned"
21         app:layout_constraintBottom_toBottomOf="parent"
22         app:layout_constraintEnd_toEndOf="parent"
23         app:layout_constraintStart_toStartOf="parent"
24         app:layout_constraintTop_toBottomOf="@+id/flow_1_visible" />
  • app:constraint_referenced_ids 指定引用的控件id或其它Flow 的id等,也可以通過tag引用
    被引用的控件原來的方位約束會失效
    按引用的順序排列
  • app:flow_wrapMode指定控件排列時自適應方式,不同方式可用的配套屬性也不一樣。
  • android:orientation 指定Flow的方向

6.1.1 app:flow_wrapMode = none(默認)

  不自適應,不換行,超過的部分不顯示,支持的屬性如下:

  • low_horizontalStyle = "spread|spread_inside|packed"
  • flow_verticalStyle = "spread|spread_inside|packed"
  • flow_horizontalBias = "float"
    僅在 app:flow_horizontalStyle="packed" 時有效,控件鏈在Flow內顯示的位置比例值,取值0-1

      app:flow_horizontalBias="0" 時

 

    

         app:flow_horizontalBias="1"

    

 

  • flow_verticalBias = "float"
    道理同上
  • flow_horizontalGap = "dimension"
    豎直排放控件時,控件的間距
  • flow_verticalGap = "dimension"
    道理同上
  • flow_horizontalAlign = "start|end"
    當flow為horizontal時,指定每個控件的對齊方式
  • flow_verticalAlign = "top|bottom|center|baseline 
    道理同上

6.1.2 app:flow_wrapMode = chain

  鏈式自適應換行,第1列/行 可以與其它列/行按不同樣式排列,屬性在none基礎上新加如下幾個:

  • flow_firstVerticalStyle 
    指定第一列的排列方式,可選值 [ spread、packed、spread_inside ]
  • flow_firstHorizontalStyle 
  • flow_firstHorizontalBias 
  • flow_firstVerticalBias
  • flow_maxElementsWrap 
    每行/列最大控件數

6.1.3 app:flow_wrapMode = aligned

  行列式自適應換行且對齊,屬性在chain基礎上減去首行相關的樣式,如下

  • flow_firstVerticalStyle 
  • flow_firstHorizontalStyle 
  • flow_firstHorizontalBias 
  • flow_firstVerticalBias

6.2 支持的操作

  • 設置大小、背景、margin、padding
  • 添加事件
  • 控制可見性
  • 動畫(只對flow對象,而是不是對其引用的控件)
  • 引用的Id也可以是其它Flow的id

7.ImageFilterView、ImageFilterButton

    它們是帶有簡單濾鏡的ImageView和ImageButton

  對比效果如下:

  

 代碼如下:

 1     <androidx.constraintlayout.utils.widget.ImageFilterView
 2         android:id="@+id/imageFilterView"
 3         ...
 4         android:background="@color/imageBg"
 5         android:src="@drawable/th"
 6         app:saturation="2"
 7         app:brightness="2"
 8         app:warmth="3"
 9         app:contrast="2"
10         app:crossfade="2"
11         app:roundPercent="1"
12         app:overlay="true"
13         />
14 
15 
16     <androidx.constraintlayout.utils.widget.ImageFilterButton
17         android:id="@+id/imageFilterButton"
18         ...
19         app:srcCompat="@drawable/th"
20         android:background="@color/imageBg"
21         app:saturation="0"
22         app:brightness="0"
23         app:warmth="5"
24         app:contrast="1"
25         app:crossfade="1"
26         app:roundPercent="0.3"
27         app:round="16dp"
28         app:overlay="true"
29         />

 

  支持的濾鏡或效果如下

altSrc Provide and alternative image to the src image to allow cross fading
saturation Sets the saturation of the image.
0 = grayscale, 1 = original, 2 = hyper saturated
brightness Sets the brightness of the image.
0 = black, 1 = original, 2 = twice as bright
warmth This adjust the apparent color temperature of the image.
1=neutral, 2=warm, .5=cold
contrast This sets the contrast. 1 = unchanged, 0 = gray, 2 = high contrast
crossfade Set the current mix between the two images.
0=src 1= altSrc image
round

(id) call the TransitionListener with this trigger id

不改圖片加圓角

roundPercent 

Set the corner radius of curvature as a fraction of the smaller side. For squares 1 will result in a circle

可以在不改變原圖的情況下,實現圓角頭像

overlay

Defines whether the alt image will be faded in on top of the original image or if it will be crossfaded with it.

Default is true. Set to false for semitransparent objects

8.本文源碼

  https://github.com/f9q/constraint2


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM