<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ConstraintLayout2.0進(jìn)階之路-歡迎新同學(xué)

          共 5165字,需瀏覽 11分鐘

           ·

          2021-02-22 18:20

          ConstraintLayout2.0針對布局來說,主要新增了兩類東西,一個是新增了VirtualLayouts,用于將一組View進(jìn)行關(guān)聯(lián)管理,并賦予定義的能力,另一個是放開了ConstraintHelper的限制。

          國際慣例,官網(wǎng)鎮(zhèn)樓。

          https://github.com/androidx/constraintlayout/wiki/What's-New-in-2.1

          https://developer.android.com/training/constraint-layout

          VirtualLayouts

          ConstraintLayout1.1首次引入了Barriers和Guidelines這樣的ConstraintHelper,它們是創(chuàng)建了一個不可見的View,讓他管理了多個View的id引用,從而實現(xiàn)多View的整體布局,例如對齊等邏輯。而在ConstraintLayout2.0中,ConstraintLayout增加了類似Flow這樣的VirtualLayouts,它允許將某些行為同時作用到所有被引用的widget上,這實際上是對這類使用場景的一種約束范式,同時統(tǒng)一了實現(xiàn)方式。

          在Constraint Layout中,VirtualLayouts作為virtual view group的角色參與約束和布局中,但是它們并不會作為視圖添加到視圖層級結(jié)構(gòu)中,而是僅僅引用其它視圖來輔助它們在布局系統(tǒng)中完成各自的布局功能。

          Flow

          Flow可以說是Chains的強(qiáng)化版,它是一種新的VirtualLayouts,可以用來構(gòu)建流式排版效果,當(dāng)出現(xiàn)空間不足的情況時,它能夠自動換行,或者是自動延展到屏幕的另一區(qū)域。當(dāng)你需要對多個View進(jìn)行流式布局,或者不確定其布局空間的實際尺寸時,就可以使用Flow來實現(xiàn)。借助官網(wǎng)上的一張圖,可以很方便的了解Flow的使用。

          6f795e079ea938574b6e41451e6da555.webp圖片

          Flow包含很多可以設(shè)置的屬性,下面通過一些例子來進(jìn)行講解。

          wrapMode

          這個屬性用于控制元素的排列方式,通過下面這個動圖,可以了解其布局的基本規(guī)則。

          a292d58e28412e97ef8ec28385c4b104.webp圖片

          Flow可以通過constraint_referenced_ids來獲取要引用的所有視圖,然后根據(jù)這些視圖創(chuàng)建一個虛擬的virtual view group,再對這些視圖進(jìn)行流式布局,示例代碼如下所示。

          ????android:layout_width="0dp"
          ????android:layout_height="wrap_content"
          ????app:constraint_referenced_ids="bt1,bt2,bt3"
          ????app:flow_wrapMode="aligned"
          ????app:layout_constraintEnd_toEndOf="parent"
          ????app:layout_constraintStart_toStartOf="parent"
          ????app:layout_constraintTop_toTopOf="parent"?/>
          • NONE : 默認(rèn)模式。Views不會被包裹到另一行或列。如果它們在屏幕之外,則不能被看到。
          • CHAIN : CHAIN與Chains非常相似,可以認(rèn)為是Chains的強(qiáng)化版本。CHAIN是根據(jù)orientation逐行或逐列進(jìn)行排列的,默認(rèn)的展示風(fēng)格是SPREAD。
          • ALIGNED : ALIGNED模式與CHAIN類似,但鏈?zhǔn)绞窃趯⒉煌泻土械囊晥D對齊后考慮的,默認(rèn)的樣式是SPREAD。

          Gap

          Gap展示了Flow中每個元素直接的間隔,這個間隔包含horizontalGap和verticalGap兩種,你可以在原有Chain Style的基礎(chǔ)上進(jìn)行額外設(shè)置,示例代碼如下所示。

          ????android:layout_width="0dp"
          ????android:layout_height="wrap_content"
          ????app:constraint_referenced_ids="bt1,bt2,bt3"
          ????app:flow_horizontalGap="50dp"
          ????app:flow_verticalGap="50dp"
          ????app:flow_wrapMode="aligned"
          ????app:layout_constraintEnd_toEndOf="parent"
          ????app:layout_constraintStart_toStartOf="parent"
          ????app:layout_constraintTop_toTopOf="parent"?/>

          Style

          當(dāng)wrapMode設(shè)置為ALIGNED或CHAIN時,根據(jù)Flow的orientation,可以設(shè)置相應(yīng)的flow_verticalStyle和flow_horizontalStyle,此時,這個Style與Chains中的Style枚舉一樣,可以設(shè)置spread、spread_inside和packed,效果也和Chains的效果一樣。

          • flow_firstHorizontalStyle:約束第一條水平鏈,當(dāng)有多條鏈(多行)時,只約束第一條鏈(第一行),其他鏈(其他行)不約束
          • flow_lastHorizontalStyle:約束最后一條水平鏈,當(dāng)有多條鏈(多行)時,只約束最后一條鏈(最后一行),其他鏈(其他行)不約束
          • flow_horizontalStyle:約束所有水平鏈
          • flow_firstVerticalStyle:同水平約束
          • flow_lastVerticalStyle:同水平約束
          • flow_verticalStyle:約束所有垂直鏈

          Bias

          當(dāng)Style設(shè)置為Packed時,可以通過Bias來設(shè)置位移的權(quán)重,這個效果與Chains的效果也是一樣的。

          Alignment

          這里的Alignment指的是Flow方向的法向方向的對齊方式,如果指定Flow的方向,是不會生效的,例如Flow的orientation是vertical,那么設(shè)置flow_horizontalAlign才會生效。

          maxElementsWrap

          表示當(dāng)前方向上最大的元素數(shù)量,這個屬性在固定行或固定列數(shù)量的時候,是非常有用的。

          在Component Tree界面,可以直接多選要創(chuàng)建Flow的Views,拖進(jìn)去自動生成constraint_referenced_ids。

          演示

          Flow是一個非常強(qiáng)大的布局工具,但是屬性也很多,所以初學(xué)者很難掌握,所以我寫了一個Demo,用于演示Flow的使用。

          be55e7d00f4802b1582faff4abb8cd38.webpimage

          代碼很簡單,詳細(xì)的可以查看 https://github.com/xuyisheng/ConstraintLayout2Demo

          ConstraintHelper

          ConstraintHelper是ConstraintLayout中的一個非常重要的部分,你可以認(rèn)為ConstraintHelper是一個用于記錄標(biāo)記Views的Helper,它并沒有創(chuàng)建新的布局,而是引用了指定的Views,并針對這個整體實現(xiàn)一些效果。

          Layer

          Layer作為一種新的輔助工具,可以認(rèn)為是Group的強(qiáng)化版,它可以讓你在多個視圖上創(chuàng)建一個虛擬的圖層。但是,與Flow不同的是,它并不會對視圖進(jìn)行布局操作,它的使用場景是對多個視圖同時進(jìn)行變換。

          例如,你需要對多個視圖整體進(jìn)行旋轉(zhuǎn)、平移或縮放操作,再或者說是設(shè)置一組View的背景,那么就可以使用Layer。

          94f39dbf6a126ea132218fda5174fcd7.webp圖片

          Layer在布局期間會調(diào)整大小,其大小會根據(jù)其引用的所有視圖進(jìn)行調(diào)整,你可以將Layer理解為一組View的邊界矩形范圍,通過Layer,可以很方便的拿到referenced_ids指定的View的邊界范圍,示例代碼如下所示。

          ????android:layout_width="0dp"
          ????android:layout_height="wrap_content"
          ????app:constraint_referenced_ids="bt1,bt2,bt3"
          ????app:flow_wrapMode="aligned"
          ????app:layout_constraintEnd_toEndOf="parent"
          ????app:layout_constraintStart_toStartOf="parent"
          ????app:layout_constraintTop_toTopOf="parent"?/>

          借助Layer,可以很方便的給一組View設(shè)置背景色的功能,這個場景在ConstraintLayout1中,只能通過新增一個View并建立與要設(shè)置背景色的一組View的約束的方式來實現(xiàn),而現(xiàn)在,使用Layer就很方便了。

          ????android:layout_width="match_parent"
          ????android:layout_height="wrap_content"
          ????android:background="#80BEBEBE"
          ????app:constraint_referenced_ids="chipOne,chipTwo,chipThree,chipFour,chipFive,chipSix,chipSeven,chipEight"
          ????app:layout_constraintTop_toTopOf="parent"?/>

          在Component Tree界面,可以直接多選要創(chuàng)建Layer的Views,拖進(jìn)去自動生成constraint_referenced_ids。

          自定義ConstraintHelper

          ConstraintHelper的三個使用場景。

          • 輔助布局:創(chuàng)建一個新的布局方式,避免創(chuàng)建新的ViewGroup從而加深層級
          • 修改布局:在布局完成后,修改布局效果
          • 重新渲染:在View繪制完成后,對View進(jìn)行修改、重新渲染效果

          常用回調(diào):

          • init:初始化調(diào)用
          • updatePreLayout:布局前更新
          • updatePostLayout:布局后更新
          • updatePostMeasure:測量后更新
          • updatePostConstraints:更新約束
          • onDraw:進(jìn)行繪制

          自定義ConstraintHelper最基本的方式就是通過繼承ConstraintHelper來實現(xiàn),并通過重寫上面的一些回調(diào),來實現(xiàn)布局的修改,下面通過一個簡單的例子來演示下如何創(chuàng)建自定義ConstraintHelper,代碼如下所示。

          class?CircularRevealHelper?@JvmOverloads?constructor(
          ????context:?Context,?attrs:?AttributeSet??=?null,?defStyleAttr:?Int?=?0
          )?:?ConstraintHelper(context,?attrs,?defStyleAttr)?{

          ????override?fun?updatePostLayout(container:?ConstraintLayout?)?{
          ????????super.updatePostLayout(container)
          ????????getViews(container).forEach?{?view?->
          ????????????ViewAnimationUtils.createCircularReveal(
          ????????????????view,?view.width?/?2,
          ????????????????view.height?/?2,?0f,
          ????????????????hypot((view.height?/?2.0),?(view.width?/?2.0)).toFloat()
          ????????????).apply?{
          ????????????????duration?=?1000
          ????????????????start()
          ????????????}
          ????????}
          ????}
          }

          updatePostLayout會在onLayout之后調(diào)用,在這里做動畫就可以。這里除了使用createCircularReveal來創(chuàng)建動畫,一般的屬性動畫也是一樣的。

          在xml布局中,只需要指定ConstraintHelper和referenced_ids即可。

          ????android:layout_width="match_parent"
          ????android:layout_height="wrap_content"
          ????app:constraint_referenced_ids="chipOne,chipTwo,chipThree,chipFour,chipFive,chipSix,chipSeven,chipEight"
          ????app:layout_constraintTop_toTopOf="parent"?/>

          ConstraintHelper還有一個好處就是可以對渲染效果進(jìn)行封裝,例如上面的CircularReveal效果,創(chuàng)建好ConstraintHelper之后,以后如果還有View需要使用CircularReveal的效果,那直接創(chuàng)建一個ConstraintHelper就可以了,實現(xiàn)了很好的復(fù)用功能。

          除了繼承ConstraintHelper來實現(xiàn)自定義的ConstraintHelper,也可以通過繼承現(xiàn)有的一些系統(tǒng)ConstraintHelper,例如Layer,這樣的好處是,可以拿到一些額外的參數(shù),方便計算,例如Layer中提供的布局邊界,這樣實現(xiàn)一個發(fā)散靠攏的效果,就很簡單了,示例代碼如下所示。

          class?FlyingHelper?@JvmOverloads?constructor(
          ????context:?Context,?attrs:?AttributeSet??=?null,?defStyleAttr:?Int?=?0
          )?:?Layer(context,?attrs,?defStyleAttr)?{

          ????override?fun?updatePostLayout(container:?ConstraintLayout)?{
          ????????super.updatePostLayout(container)
          ????????val?centerPoint?=?PointF(((left?+?right)?/?2).toFloat(),?((top?+?bottom)?/?2).toFloat())
          ????????ValueAnimator.ofFloat(0f,?1f).setDuration(1000).apply?{
          ????????????addUpdateListener?{?animation?->
          ????????????????val?animatedFraction?=?animation.animatedFraction
          ????????????????updateTranslation(centerPoint,?animatedFraction,?container)
          ????????????}
          ????????????start()
          ????????}
          ????}

          ????private?fun?updateTranslation(centerPoint:?PointF,?animatedFraction:?Float,?container:?ConstraintLayout)?{
          ????????val?views?=?getViews(container)
          ????????for?(view?in?views)?{
          ????????????val?viewCenterX?=?(view.left?+?view.right)?/?2
          ????????????val?viewCenterY?=?(view.top?+?view.bottom)?/?2
          ????????????val?startTranslationX?=?if?(viewCenterX?else?2000f
          ????????????val?startTranslationY?=?if?(viewCenterY?else?2000f
          ????????????view.translationX?=?(1?-?animatedFraction)?*?startTranslationX
          ????????????view.translationY?=?(1?-?animatedFraction)?*?startTranslationY
          ????????}
          ????}
          }

          ImageFilterButton、ImageFilterView

          ImageFilterButton繼承自AppCompatImageButton,而ImageFilterView繼承自AppCompatImageView,他們都可以實現(xiàn)對圖片的一些簡單處理,例如圓角、亮度、色相、飽和度等。

          圓角

          例如通過roundPercent和round來實現(xiàn)圓角。

          ????android:id="@+id/chipOne"
          ????android:layout_width="80dp"
          ????android:layout_height="60dp"
          ????android:background="#2962FF"
          ????app:roundPercent="1"?/>

          圖像疊加效果

          使用crossfade屬性來實現(xiàn)altSrc和src的疊加效果。altSrc提供的資源,會和src提供的資源通過crossfade屬性形成交叉淡化效果。默認(rèn)情況下,crossfade = 0,altSrc所引用的資源為不可見,它的取值范圍在0-1,借助這個屬性可以實現(xiàn)兩個Image過渡的效果動畫。

          圖片處理

          除了上面提到的這些,ImageFilterButton、ImageFilterView還支持很多簡單的圖像處理特性,下面的表中詳細(xì)介紹了。

          280234f07f7abddcedb35133812ca1c9.webpimage

          總的來說,ImageFilterButton、ImageFilterView可以幫助開發(fā)者實現(xiàn)一些簡單的圖像處理效果,不過使用場景還是比較有限。

          ConstraintLayoutStates

          ConstraintLayoutStates是ConstraintLayout2.0新增的用于切換狀態(tài)布局的一個功能,它可以根據(jù)狀態(tài)切換不同的布局文件。

          首先,需要在layout下創(chuàng)建不同狀態(tài)的layout xml文件,布局文件的root id相同即可。

          然后在xml文件夾下創(chuàng)建管理文件,代碼如下所示。

          "1.0"?encoding="utf-8"?>
          "http://schemas.android.com/apk/res/android"
          ????xmlns:app="http://schemas.android.com/apk/res-auto">

          ????????????android:id="@+id/state1"
          ????????app:constraints="@layout/states_1"?/>

          ????????????android:id="@+id/state2"
          ????????app:constraints="@layout/states_2"?/>


          在使用的時候,使用loadLayoutDescription來加載管理文件即可。

          override?fun?onCreate(savedInstanceState:?Bundle?)?{
          ????super.onCreate(savedInstanceState)
          ????setContentView(R.layout.states_1)
          ????val?constraintLayout?=?findViewById(R.id.constraint_state)
          ????constraintLayout.loadLayoutDescription(R.xml.constraint_layout_states)
          ????constraintLayout.setOnClickListener?{
          ????????constraintLayout.setState(R.id.state2,?0,?0)
          ????}
          }

          這樣就可以通過setState來實現(xiàn)狀態(tài)布局的切換了。

          ConstraintProperties

          ConstraintProperties是一個用于在代碼中創(chuàng)建約束的工具類。在2.0版本之前,我們需要這樣修改屬性,代碼如下所示。

          ConstraintSet().apply?{
          ????clone(constraintLayout)
          ????setTranslationX(R.id.xxx,?32f)
          ????setMargin(R.id.xxx,?ConstraintSet.START,?42)
          ????applyTo(constraintLayout)
          }

          而2.0提供了ConstraintProperties可以使用流式API修改屬性,代碼如下所示。

          ConstraintProperties(findViewById(R.id.xxx))
          ????.translationZ(8f)
          ????.margin(ConstraintSet.START,?8)
          ????.apply()

          在代碼中使用ConstraintLayout更加方便了。


          向大家推薦下我的網(wǎng)站?https://xuyisheng.top/??點(diǎn)擊原文一鍵直達(dá)

          專注 Android-Kotlin-Flutter 歡迎大家訪問


          瀏覽 80
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人免费三级91 | 欧美精品A片在线观看报备 | 内射视频免费观看网站免费 | 一区二区永久免费 | 无码一区二区黑人猛烈视频网站 |