現在能用 ConstraintLayout 做些什麼?
Nicolas 在谷歌負責過許多項目,比如安卓瀏覽器的 HTML5 支持,Hoenycomb 的 webview 硬體加速,還有在 JB,KitKat 上的可擴展的非相干性的圖片編輯器。然後他做了一年的機器人高速檢測系統,之後他又回到安卓開發,實現了 ConstraintLayout,現在他負責安卓開發工具的布局編輯器。
我在谷歌工作,在我工作期間,我負責安卓框架。
在過去的一年半里,我負責 ConstraintLayout。我主要的工作是開發工具,但是也有一些研發的經驗。我的 ConstraintLayout 的目標就是為了幫助開發者構建一些新的東西。
為什麼 ConstraintLayout?
如果你記得去年五月的 Google I/O,我們發布了一個特別酷的編輯器,布局編輯器。我實現 ConstraintLayout 原因就是想把它和編輯器聯繫起來。
ConstraintLayout 也好似一個非捆綁式函數庫,這個概念對於開發者和像我們這樣的庫的創建者來說,都是非常重要的概念。這對你很有用,因為你可以控制所有的事情。當你讀一些東西的時候,你能立馬得到它而且你可以自行決定是否使用。這不是推送給你的。你可以測試,而且一旦你有一個最好的版本,你就可以發布它。如果過兩天我們又發布了另一個新的版本,你不會受到任何影響。
對我們而言這也很好,這是因為下面這個原因。我們可以推送一個新的版本。我們不用擔心這會破壞任何事情。這意味著我們可以有些時候清除一些 API 或者增加一些新功能。最後,因為它是非綁定的,任何設備都能夠移植它。
RelativeLayout 是你過去可能常用的 Layout,在平面上,它和 ConstraintLayout 有許多類似的地方。你可以相對地放置你的子視圖,這第一眼看起來和 ConstraintLayout 實現的一樣。RelativeLayout 有一些你可能早就知道的問題。
這是一個完全人為的例子,但是我需要這個按鈕,它一直都需要保持在容器的左下方。
Get more development news like this
當你設置你的容器高度上容下所有的內容的時候,會發生什麼?
按鈕在底部,因為這就是 RelativeLayout 的工作方式。但是這不是我期望的行為。
如果我們在 ConstraintLayout 做同樣的事情,但你調用 wrap content,它能正常工作。
你可以也看看這些 XML,和 RelativeLayout 比起來,結果好很多。事實上,唯一新增的兩個屬性就是那兩個。它們在這裡確保了在底部和在父容器的右部的限制。其他的在 XML 裡面的屬性都是你熟知的屬性,比如 height, margin, 還有 cetera。
你可以創建一個扁平結構,這裡你可以想像布局不是非常複雜。你有一個水平的和一組垂直的布局,讓我們假設它們是 TextViews。
假設 TextView 的高度變化了,例如,父親布局需要測量。這意味著我們需要重新測量所有的元素,這目前看來是非常快的因為它們是緩存的。但是你需要從父視圖開始測量,然後這個,然後那個,直到所有的都完成。
我們需要關注布局速度的原因是你需要在 15 毫秒內完成你的布局更新,這樣 UI 才會流暢。而且如果你在 frame 裡面有許多變化的話,就會導致許多這樣的計算。結構越深,情況就會爆炸式惡化,這樣你就會有許多的 measure pass 了。
layout pass 和 measure pass: 當你知道組件的尺寸和位置的時候,布局就會發生。測量是要求你控制的這些所有的不同組件來測量自己。這開銷非常大。如果你在測量一個 TextView,你需要布局整個文欄位。測量的過程在某些方面比布局開銷還要大。我真的鼓勵你測量你的布局來確定你不會超過它們的限制。
你可能會有些擔心,比如,關於性能。目前,如果內容相似的話,它和 RelativeLayout 差不多,而且當我在 ConstraintLayout 採用同樣的布局的話 - 性能將一樣或者快點。
如果你打算完成一個扁平結構的話,你可以得到最多的好處。如果你發現一個 ConstraintLayout 很慢的例子,請發給我們。我非常自信能使得它更快些,因為有許多的優化可以做。
測量的事情怎麼辦?它和 RelativeLayout 類似,當然 RelativeLayout 會變慢。我們告訴人們它會變慢因為它總是會有兩次 layout passes。在我們的例子里,我們不這樣做;我們採用一個設置來代替。這意味著如果你想包含內容,有設置尺寸的控制項會只做一次控制項的 measure pass。如果你有一個適配限制,我們會做兩次 measures passes。
這是怎麼工作的呢?一開始,我們有線性方程解。這是你指定的線性方程在某種錯誤概率下的答案。你把它代入解中,解就會告訴你答案。
關於解,我們其實做了些微小地調整。我們知道直接修復。因為我們有限制的模式,我們能在許多的情況下,確認以前我們能夠直接解決的情況。而且在這個條件下,我們真的雙倍或者三倍加快了剩下系統的性能。
我們開發布局編輯器的原因是我們認為我們能做些事情讓你更迅速地完成 XML 的編寫。換句話說,如果你熟悉,寫 XML 是件非常快的事情。XML 不會消失,你還是需要 XML。而且,你可以在 XML 裡面使用 ConstraintLayout,這不比使用 RelativeLayout 複雜多少。
採用邊際限制,你可以說明你將移動一個控制項的邊沿到一個目標。這和 RelativeLayout 類似。你也有一個用作對齊的基準。基準就是文字的底部,所以你可以對齊兩個不同大小的按鈕,但是文字會垂直對齊。在 XML 裡面實現也是非常容易的:你開始於布局的限制,這裡你開始限制和決定你需要給目標的限制。
在這樣的情況下,約束所做的事情是,它會有邊際,這些邊際是你在同樣的地方對你的目標的限制。你可以使用元素的 ID 作為目標,也可以使用關鍵字 Parent。你和 Parent 數據相連,而且它會自動使用 Parent。
ConstraintLayout 的另外一個優點就是中心限制。如果你給同樣的控制項設置左邊和右邊的限制會發生什麼?它們不可能同時正確。
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
我們在這個例子裡面想做的事情是居中。在這個例子裡面,不帶偏見,默認值都是 50%,這會使得控制項居中。你可以移動它,然後把它改成其他的東西,這會使得你構建一個更具有擴展性的 UI。
還有尺寸限制。你描述一個固定尺寸或者使用包含內容來獲取控制項自己的尺寸。但是不要使用 match parent,因為這是不支持的,我們使用 Match Constraint。你可以指定一個比率,再給 ConstraintLayout 加上一個最大的高度和寬度。
Match Constraint. Match Constraint 意味著替代 Wrap Content 或者一個固定尺寸,你使用 zero DP,這和線性 layout 裡面用法類似。這樣的結果就是它會找到控制項的尺寸來符合那些限制條件。如果你的控制項是 Wrap Content,通過設置 Match Constraint,它就會擴大。你可以指定 margin,這樣它就會比 margin 的尺寸略小一些。
app:layout_constraintDimensionRatio="h,1:1"
關於比率,你唯一需要做的事情就是給 Match Constraint 設置一個尺寸。當你想使用解給你的尺寸的時候,採用 zero DP 並且指定比率。你應該指定這個屬性,和 Match Constraint 的一個尺寸。
許多人不知道 View.GONE。當你有 View A 和 受制於 A 的 View B 的時候,我們想給 View A 設為 GONE。以下事情將會發生:當 A 被移除的時候,它還是會被方程使用。A 僅僅變成了一個單點,將會移出邊界。你的 A 和 B 之間的留白變成了和 A 還在那裡的時候一樣,A 沒有消失。
app:layout_goneMarginLeft="60dp"
你可以給某些東西指定一個 GONE Margin,而且指定你想要的任何值。在這個例子里,當你想限制的目標被標為 GONE 的時候。一個最近增加的強大功能是 Chains。一個 chain 會被認為是一個雙向的限制。在至少兩個控制項中間的相反方向的限制。
你在這個 XML 裡面實現的方式不是非常直觀,但是你可以把它看作從右到左的按鈕。左邊是在父親上的,而且你右邊也是在父親上的,但是左邊接著右邊的另一個按鈕。你可以看到這是雙向反向的限制。
限制你有一個 chain,你可以做些有意思的事情。首先,在 chain 開始的地方,如果你設置具體的屬性,這會導致 chain 的行為。那些是我們支持的 chain 的風格。簡單地創建你的 chain 然後指定風格,比如 spread, spread inside, widget all packed, 你會得到不同的結果。
控制項和指定的風格的行為有些不同,控制項會打開。在這種情況下,B 和 C 是 zero DP 而且默認的行為是平分空間。你可以讓一個控制項比另外一個獲得的空間多些。
一個 chain 的風格是封裝好的。你可以應用 bias,這樣你能夠把 chain 看作 Linear Layout 裡面的 Group 類似的東西。不同之處就是它給了你在類似軸上的行為。這使得你可以實現那些現在或者以前使用類似 Linear layout 來構建的 UI。
app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintHorizontal_chainStyle="spread_inside" app:layout_constraintHorizontal_chainStyle="packed"
Guidelines 的想法是讓我們可以有些東西幫助你創建 UI。而且你可能認為它和 Editor 幫助你的方法類似,但是實際上它們不能幫助你完成最後的 View 結構。在下面這個 Guideline 的例子中,透傳後它就消失了,而且都展開。這裡是個 XML 的例子。
最後我想說的事情就是 Constraint Layout 里的 ConstraintSet。
ConstraintSet mConstraintSet1 = new ConstraintSet(); // create a Constraint Set ConstraintSet mConstraintSet2 = new ConstraintSet(); // create a Constraint Set mConstraintSet2.clone(context, R.layout.state2); // get constraints from layout setContentView(R.layout.state1); mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main); mConstraintSet1.clone(mConstraintLayout); // get constraints from ConstraintSet TransitionManager.beginDelayedTransition(mConstraintLayout); mConstraintSet1.applyTo(mConstraintLayout
這裡的想法是你有這個扁平的布局。扁平布局的一個很棒的地方就是使得對齊容易了很多。如果你做些動畫,或者在很深的嵌套布局中使用動畫,你會有各種各樣的問題。如果你有扁平的設計,線性動畫會效果更好。
ConstraintSet 使你能夠更進一步。他能夠做的事情就是抓住一組限制,然後你能夠保持這些數據。
我可以展示一個按鈕,然後拖動它。首先你需要注意的事情就是我能夠把它放到任何位置。限制,它不受限制。事實上,如果我打開 XML 文件,你可以看到 Editor 正在抱怨它不受限制。
你可能還聽說過 blueprint 模式。你能想像這個 blueprint 模式就好像 x-ray 模式。它接受你當前的 view 然後給你顯示相關的布局。某種程度上,它就是 xml 屬性的視圖模式。而且是一一對應的。
我個人很喜歡 blueprint 模式因為我想它可以讓基本的事情更加清楚些。你可以使用設計模式。默認情況下,我們不顯示限制,除非你在上面停留。
我希望你們能得到這個工具的背景知識。使用它肯定不止一種方法。我們儘力想為你,按照你的想法使用這個工具,提供不同的路徑和體驗。
如果你真的是一個 XML 的高效使用者,你可以繼續使用 XML 而且你可以在這裡預覽。預覽框不僅僅是一個預覽框,它還是一個成熟的編輯器,使你能夠改變些東西。
接下來是快速一覽。我們當然希望實現更多的靈活性。如果你使用 Conversion 工具,它使得你能夠使用老的布局文件,而且轉換它。
請開 bug,聯繫我,不用猶豫。
※PHP白盒審計工具RIPS源碼簡析
※C#7.1先睹為快
※國內Foscam製造的IP攝像頭被曝出大量漏洞
※動態添加Redis密碼認證
※史玉柱、雷軍是如何從定位理論中找到營銷爆點的?
TAG:推酷 |
※Burberry by Riccardo Tisci?讓我們從現在就開始期待!
※現在用的是iphone6,是換iPhone8 plus還是iPhone X?
※iRig Keys I/O 集成控制現在可以兼容 GarageBand和Logic Pro X
※通過 Docker 實現在 Linux 容器中運行 Microsoft SQL Server 資料庫
※mastermind JAPAN x Carhartt WIP聯名釋出,現在原價入手還困難么?
※Cellebrite說它現在可以解鎖運行iOS 11的設備,包括iPhone X
※現在買iphone7 plus好,還是iphone8 plus好呢?
※python是什麼語言?現在學Python好找工作嗎?
※Angelababy為什麼現在這麼紅?
※Salesforce數據現在可以導入到Google Analytics 360中了
※您的Apple iCloud數據現在存儲在Google伺服器上-感到驚訝嗎?
※感到驚訝嗎?Apple iCloud數據現在存儲在Google伺服器上
※球鞋變漫畫還不夠?現在adidas Skateboarding直接讓漫畫里服飾穿上身!
※劉海屏因Essential Phone而起,現在又由它來終結?
※微軟小娜已支持iPad使用,現在你甚至可以,嘿siri,打開Cortana
※曾經的Windows Phone死忠紐約警局現在要換iPhone 7
※human being到tech being,我去聽了一場「站在未來看現在」的燒腦科技演講
※現在買iPhone 7 Plus過時嗎?
※Android版iPhone X 們,現在有了最適合自己的處理器
※易主一年後的 American Apparel 現在怎麼樣了