###### tags: `Android` `Kotlin` `View` # ConstraintLayout 早期Android畫面是由xml去編寫的,雖然也有提供介面讓開發者操作,但還是有些不直觀 因此在2016的Google I/O大會發表了 ConstraintLayout 來解決問題 在它出現之前有一個類似的元件RelativeLayout(透過相對位置布局) 但ConstraintLayout更為靈活,其優點是易於構造出複雜的布局 ## 佈局方式 ### XML布局 約束布局可以用GUI介面拉線,也可以用XML編寫對應關係 我自己的習慣是一開始先用GUI拉,之後再用XML做細節修改 因為有時候元件多真的不好拉線XD,以下介紹幾個常用的屬性: ```xml= app:layout_constraintTop_toTopOf="parent" 約束布局的核心,即約束條件,指該元件的頂部對應其他元件的頂部 app:layout_constraintHorizontal_weight="1" 約束布局也可以實現線性布局的權重特性,搭配Chains使用 app:layout_constraintHeight_percent="0.5" 可以用百分比制定高度與寬度大小,由上而下,由左而右 app:layout_constraintDimensionRatio="1:1" 元件的寬高比,需將寬高其中一個設為0dp app:layout_constraintVertical_bias="0.5" 垂直水平偏差,可以用百分比制定元件在不同螢幕尺寸下的位置 app:layout_goneMarginTop="8dp" 當Top對應的對象gone時,會讓此元件產生Top間距 ``` > https://juejin.im/post/5a322f2251882552de5e2994#heading-16 ### 動態布局 先介紹在編碼中幾個相關的類別: - ConstraintLayout 約束布局實體(對象) - ConstraintSet 設置約束條件的核心(官方推薦) - ConstraintLayout.LayoutParams 設置 layout 參數(官方不推薦) - Guideline 對齊線,輔助約束條件的設置 :::success 在其他 layout 方式中通常會用 LayoutParams 調整參數 但在 ConstriantLayout 官方不推薦用這個來調整,而是用 ConstraintSet ::: 如何動態生成 首先要建立約束布局的實體(可編碼生成,也可藉XML元件的id,這裡不贅述...) 再來要設置約束條件,有兩種方式: 假設val set = ConstraintSet() - connect 手動設置連結 ```kotlin set.connect(該元件id, 該元件位置, 目標元件id, 目標元件位置, 外距) //代碼中為px需轉為dp ``` - clone 複製已存在的約束布局中的約束條件(要注意子元件都必須要有id,否則報錯) ```kotlin //兩種方式 set.clone(constraintLayout) //連接變數 set.clone(context, R.layout.constraintLayout) //連結xml的元件id ``` 外距取得: ```kotlin= private fun getDp(dp: Int): Int { val displayMetrics = context.resources.displayMetrics return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)) } ``` 最後將約束條件指定給約束布局就完成囉! ```kotlin //兩種方式 set.applyTo(constraintLayout) constraintLayout.setConstraintSet(set) ``` ### 疑難雜症 使用動態布局時,想要讓元件消失或顯示,貌似不能用普通的View.visibility 即使View.visibility的值是可見的,但在運行上還是看不到 當時遇到這個問題讓我很困惑,雖然至今還是想不透,但找出以下的解決辦法填坑 實際測試此元件的visibility,在約束申請完成後,就變成可見了 ```kotlin set.setVisibility(元件id, ConstraintSet.VISIBLE) ``` ### 參考文章 http://xgfe.github.io/2017/09/17/ivanchou/layout-with-constraintlayout-by-programming/ https://www.jianshu.com/p/90604ef829eb ## 屬性介紹 接下來介紹 ConstraintLayout 有哪些有趣的屬性 ### 強制約束 如果元件設定為 wrap_content,那 maxWidth、minHeight 這些屬性會失效 而強制約束就是在元件設定為 wrap_content 的情況下依然可限制長寬 只要將 layout_constrainedWidth 設為 true 即可 參考文章:https://www.jianshu.com/p/4b23e789befb ### Chain 鏈 LinearLayout 有一個重要特性就是子元件的比例分配,例如:均分、權重分配 而 ConstraintLayout 的比例分配就是使用 Chain 來完成,它跟 LinearLayout 一樣有水平、垂直 ==建立 Chain== 兩個元件互相對齊就可以建立一個 Chain ==Chain Head== 鏈頭是指一個鏈的第一個元件,Chain 的重要屬性必須在 Head 中設定,例如:Style ==Chain Style== 主要有 3 種:spread、spread inside、packed 搭配權重、偏移就會再加上 2 種:weight、bias - Spread Chain:所有元件互相均分,鏈的默認風格 - Spread Inside Chain:頭至頂、尾至底,中間元件互相均分 - Weighted Chain:元件權重分配 - Packed Chain:所有元件互相貼合並置中 - Packed Chain with Bias:所有元件互相貼合並偏移 ### Barrier 屏障 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/1017/8601.html ### Placeholder 佔位 ### 2.0 [ConstraintLayout 2.0 — Flow、Layer、MotionLayout](https://medium.com/evan-android-note/constraintlayout-2-0-94d0c0fd34e0)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up