ConstraintLayout基礎(chǔ)系列之尺寸橫縱比 dimensions

2018-06-06 18:25 更新

原文:ConstraintLayout basics guidelines 作者:Mark Allison


ConstraintLayout的尺寸 dimensions

有時(shí)候,我們需要?jiǎng)?chuàng)建一些固定方向比的 View 組件,最常使用固定橫縱比的就是當(dāng) ImageView 用于展示一些固定橫縱比的圖片的時(shí)候。舉些例子,書面封面(尺寸橫縱比多種多樣),電影海報(bào)(一般是 4:6 ),電影劇照(一般是 1.85:1 或 2.39:1 ),電視?。ㄒ话闶?4:3 或 16:9 )

對(duì)于不熟悉什么是橫縱比的,橫縱比就是表示了 View 的寬度與高度的比例 w:h 。例如,對(duì)于一個(gè)擁有橫縱比為 4:6 擁有寬度為 40dp 的 View 組件有著高度是 60dp ,若它的寬度改為 30dp 則它的高度就是 45dp

若我們現(xiàn)實(shí)的圖片能保證同樣的橫縱比和像素大小,我們可以簡(jiǎn)單的在兩個(gè)方向上使用 wrap_content 即可。然而,現(xiàn)實(shí)情況由于數(shù)學(xué)四舍五入等多種原因都有可能造成實(shí)際現(xiàn)實(shí)的一些小誤差。如果只是現(xiàn)實(shí)一個(gè)圖片可能不會(huì)有多大問題,但是如果多個(gè)圖片展示的時(shí)候小問題也會(huì)被有很不好的視覺效果,甚至當(dāng)有 View 對(duì)齊于這些圖片的 ImageView 的時(shí)候,也因此產(chǎn)生了變化,整體就會(huì)造成布局不平衡混亂了。

對(duì)于這個(gè)問題的解決方案之一是,通過創(chuàng)建繼承于 ImageView 的子類,并通過覆寫 onMeasure() 來實(shí)現(xiàn)固定橫縱比的布局。常用的 support library 中的 PercentLayout 也提供了一些機(jī)制來結(jié)局這類橫縱比問題。

同樣的 ConstraintLayout 也提供了機(jī)制來專門解決這個(gè)問題,選擇想要控制橫縱比的 View 然后通過屬性視圖中修改 ratio 值來改變橫縱比,如下圖紅色圈內(nèi)設(shè)置:

如上圖,我們?cè)O(shè)置的 View 組件有著向父組件的 start 和 top 邊緣的約束,它的 end 邊緣則約束向一條參考線,而 bottom 邊緣則沒有被約束,這個(gè) View 的 layout_widthlayout_height 都被設(shè)置成 match_constraint,表示他們會(huì)根據(jù)所有的約束來設(shè)置寬高。在布局階段這個(gè)組件的寬度就被計(jì)算好了,但是它的高度好像沒有被確定。然后,因?yàn)樵O(shè)置了寬高橫縱比,高度其實(shí)也被確定了,只是寬度的一個(gè)函數(shù)輸出值(在以上例子中橫縱比是 16:9 )

這樣設(shè)置的好處就是,當(dāng)寬度變化的時(shí)候,高度自動(dòng)跟著變化,如下圖通過移動(dòng)這個(gè) View 組件 end 邊緣約束向的參照線就可以看到效果。

在 XML 中的尺寸橫縱比 DimensionRatio

上例中的 XML 源碼如下:

<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.stylingandroid.scratch.MainActivity">


  <View
    android:id="@+id/imageView"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    app:layout_constraintDimensionRatio="h,15:9"
    app:layout_constraintEnd_toStartOf="@+id/guideline"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />


  <android.support.constraint.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.39" />


</android.support.constraint.ConstraintLayout>

可以發(fā)現(xiàn),設(shè)置橫縱比的屬性是 app:layout_constraintDimensionRatio ,而這個(gè)值有兩個(gè)部分組成:方向和比例值。

通過上面的視圖編輯器,我們已經(jīng)知道了寬度就是輸入的固定值,從而設(shè)置了方向是 h 標(biāo)識(shí)了 horizontal 。其實(shí)這個(gè)方向可以不用設(shè)置,在運(yùn)行時(shí)的 layout 布局過程就可以計(jì)算推斷出來,但顯示的在 xml 源碼中聲明避免了所有可能出現(xiàn)模棱兩可的情況發(fā)生。在大多數(shù)情況下,這非常不必要因?yàn)楸旧矸较蚴遣谎宰悦鞯?,就像例子中,唯有高度沒被約束,很容易推斷出來高度是根據(jù)寬度來的變量函數(shù)。

這種橫縱比的組件往往又很大的說服力,當(dāng)橫縱比的權(quán)利被賦予的時(shí)候。

最后還要提到的是,上文提到的寬高屬性被設(shè)置成 match_constraint 實(shí)際上在 XML 源碼中表現(xiàn)是被設(shè)置成 0dp,這就像 LinearLayoutweight 屬性一樣,會(huì)在 XML 中設(shè)置為 0dp ,而實(shí)際大小會(huì)根據(jù)父組件在布局 layout 過程中的大小來決定計(jì)算出來。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)