ConstrainLayout實(shí)踐

已有很多關(guān)于ConstrainLayout的介紹,偏向?qū)傩缘幕A(chǔ)介紹,主要講述了具有哪些屬性和基準(zhǔn)線的屬性,但到了實(shí)際項(xiàng)目中,光是知道屬性是遠(yuǎn)不夠的,完整一個(gè)略微復(fù)雜的界面,就需要屬性之間的組合使用。
而ConstainLayout屬性之前有相互牽制(當(dāng)然啦,該布局本來(lái)就叫約束布局,從屬性的使用中也體現(xiàn)出了這個(gè)概念),有的屬性A,由于另一個(gè)屬性B的不再設(shè)置,就失去A屬性的作用。
初次使用,會(huì)暈頭轉(zhuǎn)向,怎么剛剛還有效果的,加了個(gè)屬性或者改了某個(gè)已經(jīng)在的屬性的值,布局就亂套了。
總而言之,孰能生巧,體會(huì)該布局的核心思想,先規(guī)劃布局,再動(dòng)手實(shí)踐。

屬性簡(jiǎn)介

先稍微回顧一下屬性,這里只做簡(jiǎn)單羅列。

1.寬高比例
layout_constrainDimensionRatio:"w,13:2"/"h, 23:23",其中w,h可以不注明, 默認(rèn)為寬高比
2.位置對(duì)齊
layout_constraintLeft_toLeftOf: 將目標(biāo)控件的左側(cè)牽引到另外一個(gè)控件的左側(cè)
layout_constraintRight_toLeftOf: 將目標(biāo)控件的右側(cè)牽引到另外一個(gè)控件的左側(cè)
layout_constraintLeft_toRightOf: 將目標(biāo)控件的左側(cè)牽引到另外一個(gè)控件的右側(cè)
layout_constraintRight_toRightOf: 將目標(biāo)控件的右側(cè)牽引到另外一個(gè)控件的右側(cè)
layout_constraintTop_toTopOf: 將目標(biāo)控件的上側(cè)牽引到另外一個(gè)控件的上側(cè)
layout_constraintTop_toBottomOf: 將目標(biāo)控件的上側(cè)牽引到另外一個(gè)控件的下側(cè)
layout_constraintBottom_toTopOf: 將目標(biāo)控件的下側(cè)牽引到另外一個(gè)控件的上側(cè)
layout_constraintBottom_toBottomOf: 將目標(biāo)控件的下側(cè)牽引到另外一個(gè)控件的下側(cè)
================
layout_constrainStart_toEndOf:將目標(biāo)控件的左側(cè)與另一控件的右側(cè)對(duì)齊
layout_constrainStart_toStartOf:將目標(biāo)控件的左側(cè)與另一控件的左側(cè)對(duì)齊
layout_constrainEnd_toStartOf:將目標(biāo)控件的右側(cè)與另一控件的左側(cè)對(duì)齊
layout_constrainEnd_toEndOf:將目標(biāo)控件的右側(cè)與另一控件的右側(cè)對(duì)齊

3.基線對(duì)齊

layout_constrainBaseline_toBaselineOf:與目標(biāo)控件的基線對(duì)齊

4.基準(zhǔn)線【GuideLine】

orientation:vertical/horizontal  基準(zhǔn)線的方向
layout_constrainGuide_begin:基準(zhǔn)線起點(diǎn)
layout_constrainGuide_end:基準(zhǔn)線終點(diǎn)
layout_constrainGuide_percent:基準(zhǔn)線百分比模式,用于指定位置

5.牽引線

layout_constrainHorizontal_bias:水平方向上的牽引力
layout_constrainVertical_bias:垂直方向上的牽引力

6.鏈樣式

layout_constrainHorizontal_chainStyle:水平方向上的樣式
layout_constrainVertical_chainStyle:垂直方向上的樣子
layout_constrainVertical_weight:設(shè)置該控件在鏈中的權(quán)重

可以設(shè)置鏈樣式的屬性值


image.png

實(shí)踐

實(shí)現(xiàn)如下圖該界面布局


image.png

實(shí)現(xiàn)方式:一般的使用一般的嵌套布局也可以實(shí)現(xiàn),主要原因是層次會(huì)比較深,還會(huì)影響頁(yè)面繪制的時(shí)間。
約束布局:其優(yōu)勢(shì)是扁平式的局部方式,繪制時(shí)間短。
小結(jié):當(dāng)然啦,如果只是簡(jiǎn)單地實(shí)現(xiàn)整個(gè)界面,兩種方式前者除了繪制上的劣勢(shì)似乎沒(méi)有其他什么比較大差別。而約束布局ConstrainLayout的使用門檻則相對(duì)高一些,但當(dāng)開(kāi)發(fā)者已經(jīng)熟練掌握,信手拈來(lái)時(shí),那絕對(duì)是酸爽,不過(guò)出現(xiàn)某條屬性導(dǎo)致的“牽一發(fā)而動(dòng)全身”的后果。

另外:
基于作者君的業(yè)務(wù)場(chǎng)景,用戶在觀看影片的同時(shí),出現(xiàn)小半屏幕的掃碼界面。界面除了要適配不同分辨率的機(jī)型,由于不同業(yè)務(wù)方自身的UI風(fēng)格,對(duì)于界面站整個(gè)屏幕的比重也有自身的要求。因此希望開(kāi)放設(shè)置寬度屏占比、高度屏占比的接口,即對(duì)接方的開(kāi)發(fā)者通過(guò)一個(gè)方法設(shè)置浮層整體的寬高屬性值。作者君的UI設(shè)計(jì)需要需要保證整體內(nèi)容位置的美觀效果不變。
基于上訴業(yè)務(wù)需求,采用一般的嵌套布局實(shí)現(xiàn),從達(dá)到視覺(jué)結(jié)果來(lái)看,沒(méi)什么問(wèn)題,但今天的重點(diǎn)是ConstrainLayout的實(shí)踐,因此著重講述它的實(shí)現(xiàn)。

好啦,如果讀者不理解作者君的業(yè)務(wù)場(chǎng)景,就直接略過(guò)上面的話。注重看用那ConstrainLayout來(lái)實(shí)現(xiàn)如上圖的界面吧。

1.控制布局位置:Guideline的使用,限定整個(gè)界面位于右側(cè)。

Guideline是不占大小的一條輔助線,可以用來(lái)占位、劃分區(qū)域、作為定位其他view的基準(zhǔn)線。
例如項(xiàng)目中淘客二維碼界面,需要展示在屏幕的右邊
主要使用了如上述所說(shuō)的四個(gè)屬性:

orientation:vertical/horizontal  基準(zhǔn)線的方向
layout_constrainGuide_begin:基準(zhǔn)線起點(diǎn)
layout_constrainGuide_end:基準(zhǔn)線終點(diǎn)
layout_constrainGuide_percent:基準(zhǔn)線百分比模式,用于指定位置。

具體使用如下:

<!---頂部水平分割線  --!>
   <android.support.constraint.Guideline
        android:id="@+id/horizontalGuideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"/>
    <!--右側(cè)視圖分割線線---!>
    <android.support.constraint.Guideline
        android:id="@+id/verticalGuideline"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:orientation="vertical"
        app:layout_constraintGuide_end="519dp"
        app:layout_constraintRight_toRightOf="parent" />
<!---底部水平分割線 :注意用percent值來(lái)設(shè)置居于底部是為屏幕高度的適配,不建議用end或start --!>
    <android.support.constraint.Guideline
        android:id="@+id/horizontalGuideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="1.0" />
    
    <View
        android:id="@+id/view2"
        android:layout_width="wrap_content" //注意,這里必須是wrap_content,不用擔(dān)心  
        android:layout_height="wrap_content"http://view無(wú)法展示,事實(shí)上,則是它是占滿右側(cè)的
        android:background="@color/color99001122"
        app:layout_constraintLeft_toRightOf="@id/verticalGuideline"
        app:layout_constraintTop_toTopOf="@id/horizontalGuideline"
        app:layout_constraintBottom_toBottomOf="@id/horizontalGuideline2"/>

看一下實(shí)現(xiàn)后的效果:水平的GuideLine和垂直的GuieLine。此時(shí)改變GuideLine的屬性就可以改變黑色區(qū)域的大小。OK背景色已經(jīng)寫(xiě)完。(注意:約束布局是一種扁平的布局,所有view都是同級(jí)的,不存在嵌套約束關(guān)系,
所以界面上需要擺放的其他view也要通過(guò)約束位置來(lái)實(shí)現(xiàn)上下壓縮,左側(cè)拉伸時(shí),位置能夠相對(duì)友好,以滿足視覺(jué)需求。)

layout_constrainGuide_begin:基準(zhǔn)線起點(diǎn)
layout_constrainGuide_end:基準(zhǔn)線終點(diǎn)
//當(dāng)GuideLine屬性值改變時(shí),View的大小會(huì)發(fā)生變化,但其width和height仍然為wrap_content.
//當(dāng)然還可以使用百分比的方式:
layout_constrainGuide_percent:基準(zhǔn)線百分比模式,用于指定位置
image.png

2.水平居中放置互聯(lián)view:Chain的使用

約束view位于水平線的下方
layout_constraintTop_toBottomOf
【頂部線的位置被壓縮后,view也自動(dòng)向下移動(dòng)】
view水平居中對(duì)齊
=========
layout_constraintEnd_toStartOf
layout_constraintStart_toEndOf
這兩個(gè)屬性來(lái)確認(rèn)相鄰view之前的關(guān)系(可能會(huì)想為什么讓不用left_ToRight等屬性,也可能讓三個(gè)view排成一排啊、是可以排成一排,但設(shè)置的下面屬性就失效了。建議自己寫(xiě)一下感受下。)
============
layout_constraintHorizontal_chainStyle
設(shè)置chainStyle的不同值,view之間的間距會(huì)不一樣。(回顧上文的藍(lán)色圖)
設(shè)置所有view距離頂部線的高度一致
1. 可以分別設(shè)置每個(gè)view的marginTop
2.也可以設(shè)置首個(gè)view的marginTop,其他view與它Top_toTop對(duì)齊。
3.或者其他我沒(méi)有想到的更好的方案............

 <ImageView
        android:id="@+id/iv_detail_pop_taobao"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="@drawable/saoma_taobao"
        android:layout_marginTop="50dp"
        app:layout_constraintTop_toBottomOf="@id/horizontalGuideline"
        app:layout_constraintEnd_toStartOf="@id/iv_detail_pop_tmall"
        app:layout_constraintStart_toEndOf="@id/verticalGuideline"
        app:layout_constraintHorizontal_chainStyle="packed" //設(shè)值緊湊模式
        android:layout_marginRight="20dp"  //通過(guò)marginRight來(lái)自定義彼此之間的間距
        />
    <ImageView
        android:id="@+id/iv_detail_pop_tmall"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="@drawable/saoma_tianmao"
        app:layout_constraintTop_toTopOf="@id/iv_detail_pop_taobao"
        app:layout_constraintEnd_toStartOf="@id/iv_detail_pop_alipay"
        app:layout_constraintStart_toEndOf="@id/iv_detail_pop_taobao"
        android:layout_marginRight="20dp"
        />
     <ImageView
        android:id="@+id/iv_detail_pop_alipay"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="@drawable/saoma_zhifubao"
        app:layout_constraintTop_toTopOf="@id/iv_detail_pop_taobao"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/iv_detail_pop_tmall"
image.png

文字一行的擺放也是如此,不再贅述。
讓某個(gè)text居中就更容易了,只要指明他左邊或右邊的參照物,或者start 和end的參照物,就可以在兩個(gè)參照物之間居中

 <TextView
        android:layout_width="wrap_content"
        android:layout_height="32dp"
        android:layout_marginTop="20dp"
        android:text="該寶貝需掃碼購(gòu)買"
        android:textColor="@color/colorWhite"
        android:textSize="22sp"
        app:layout_constraintLeft_toRightOf="@id/guideline2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_tmall_title" />

實(shí)現(xiàn)效果

image.png

圖片隨寬高自伸縮
UI需求描述:居中且大小可伸縮的圖片,讓圖片左右兩側(cè)的間隙保持一個(gè)百分比定值。比如左右側(cè)始終為10%間距。
約束布局沒(méi)有可以設(shè)置間距大小為百分比的屬性,這里采用重新設(shè)置圖片寬高的屬性來(lái)達(dá)到目的。
根據(jù)開(kāi)發(fā)這傳入的整體寬度值500,計(jì)算圖片的大小為 500-210%500=400,即圖片大小為400*400,常規(guī)的做法需要通過(guò)代碼動(dòng)態(tài)修改圖片的寬、高值。這里使用了約束布局的一個(gè)屬性:設(shè)置寬高比,只需重寫(xiě)一個(gè)值,略簡(jiǎn)單。

app:layout_constraintDimensionRatio="1:1"

那么在代碼中只需要設(shè)置寬與高其中一個(gè)值就可以保持1:1的大小
指定寬高之一為定值,剩下的一個(gè)必須為0dp。


image.png

最后一行文字的位置也就很簡(jiǎn)單了:以底部guideLine的基準(zhǔn)線,再設(shè)置偏移位置。

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="客服電話:0571-851378778"
        android:textColor="@color/coloraabbcc"
        android:textSize="18sp"
        android:layout_marginBottom="50dp"
        app:layout_constraintBottom_toBottomOf="@id/horizontalGuideline2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@id/verticalGuideline"
        />

由于為了保證美觀性,自適應(yīng)布局在UI設(shè)計(jì)時(shí)會(huì)以最小與最大情況考慮各類圖片的大小和其間距,所以并非所有的尺寸都要縮放(如上述的白色方塊圖為例子)。如果要做到縮放,則需要通過(guò)代碼動(dòng)態(tài)地設(shè)置大小,目前還不支持百分比。

到這里為止,幾乎約束布局的所有類型的屬性都已經(jīng)用了一遍。重點(diǎn)思考和實(shí)現(xiàn),在這過(guò)程中體會(huì)約束布局的美妙~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,204評(píng)論 3 119
  • 簡(jiǎn)單的使用for和while語(yǔ)句實(shí)現(xiàn)循環(huán) while循環(huán) while語(yǔ)句反復(fù)執(zhí)行循環(huán)體中的語(yǔ)句,直到相關(guān)表達(dá)式求值...
    東飛閱讀 2,884評(píng)論 0 4
  • 讀書(shū)可以是一種使人心平氣和的消遣。一杯茶,一本書(shū),累了就閑庭信步,淡看云卷云舒。這是一個(gè)令人向往的場(chǎng)景,就像不少女...
    半瓶六紳閱讀 381評(píng)論 0 0
  • 約翰尼.德普1994年拍的電影,今天終于看了,留下了深刻印象,作為艾德.伍德的傳記電影,我想,如果我自己不夠好,只...
    搗蛋的倒霉熊閱讀 286評(píng)論 0 1

友情鏈接更多精彩內(nèi)容