Android 3分種看懂 ConstraintLayout 替代LinearyLayout和RelativeLayout

面試問題:

1.位置約束
2.寬高約束  width
3.重疊:gudlie
4.鏈:sytle
5.權重
6.動畫
7.2.0特性

 

 

ConstraintLayout在項目中實踐與總結

 
 

我的理解:

2個字約束
1.位置約束
2.尺寸約束(寬高約束)
 
Flow的用法:2.0特性
3.可以像ios一樣,進行拖動

添加依賴

<span style="color:#000000"><span style="color:#cccccc"><code class="language-bash"> implementation 'com.android.support.constraint:constraint-layout:1.1.3'</code></span></span>

相對定位:替代RelativeLayout的用法

TextView2在TextView1的右邊,TextView3在TextView1的下面
<span style="color:#000000"><span style="color:#cccccc"><code class="language-objectivec"> <span style="color:#67cdcc"><</span>TextView
        android:id<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView2"</span>
        ...
        app:layout_constraintLeft_toRightOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView1"</span> <span style="color:#67cdcc">/</span><span style="color:#67cdcc">></span>

    <span style="color:#67cdcc"><</span>TextView
        android:id<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView3"</span>
        ...
        app:layout_constraintTop_toBottomOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView1"</span> <span style="color:#67cdcc">/</span><span style="color:#67cdcc">></span></code></span></span>
    
下面來看看相對定位的常用屬性:
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf:和相對佈局的區別,最左邊默認是另外一個控件的最右邊,但是約束佈局不是,可能是最左邊是另外一個的最左邊
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
 
start====end和left=====Right  ,2者的區別是什麼?
適應不同國家,因爲有些阿拉伯國家是右到左
 
layout_constraintTop_toTopOf:1個控件相對於另外一個控件,可以保持頂部對齊
總結:第一個值代碼參考值view,後面to和releative是一樣的、
 
 
 
 
 

居中

第一中居中方式
把控件放在佈局中間的方法是把layout_centerInParent設爲true
<span style="color:#000000"><span style="color:#cccccc"><code class="language-bash">app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"</code></span></span>
 
RelativeLayout中的水平居中layout_centerHorizontal相當於在ConstraintLayout約束控件的左右爲parent的左右;
RelativeLayout中的垂直居中layout_centerVertical相當於在ConstraintLayout約束控件的上下爲parent的上下。
第二種居中:c如何在a,b的中間
 
 
第三種居中:
 
 
 
 
 
 
第四種居中:
 
 
 
 
第五種居中:
 
layout_constraintBaseline_toBaselineOf
如圖所示,兩個TextView的高度不一致,但是又希望他們文本對齊,這個時候就可以使用layout_constraintBaseline_toBaselineOf
 
 
第六
 
 
種居中:
 
 
 
替代LinearyLayout
 

尺寸約束

使用 0dp (MATCH_CONSTRAINT)
官方不推薦在ConstraintLayout中使用match_parent,可以設置 0dp 
width:0dp代表的含義:服從約束
很多時候width==0的作用
 
 
widthsytle:也有3種屬性
 
 
 
<span style="color:#000000"><span style="color:#cccccc"><code class="language-objectivec"><span style="color:#67cdcc"><</span>TextView
        android:id<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView1"</span>
        android:layout_width<span style="color:#67cdcc">=</span><span style="color:#7ec699">"0dp"</span>
        android:layout_height<span style="color:#67cdcc">=</span><span style="color:#7ec699">"wrap_content"</span>
        android:layout_marginLeft<span style="color:#67cdcc">=</span><span style="color:#7ec699">"50dp"</span>
        app:layout_constraintLeft_toLeftOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"parent"</span>
        app:layout_constraintRight_toRightOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"parent"</span>
        android:visibility<span style="color:#67cdcc">=</span><span style="color:#7ec699">"visible"</span> <span style="color:#67cdcc">/</span><span style="color:#67cdcc">></span></code></span></span>
寬設置爲0dp,寬高比設置爲1:1,這個時候TextView1是一個正方形
 
替代方法:權重鏈
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-xml">layout_constraintHorizontal_weight:橫向的權重

layout_constraintVertical_weight:縱向的權重</code></span></span></span>
width=0dp, layout_constraintHorizontal_weight設置權重大小
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-objectivec"> <span style="color:#67cdcc"><</span>TextView
        android:id<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView1"</span>
        android:layout_width<span style="color:#67cdcc">=</span><span style="color:#7ec699">"0dp"</span>
        android:layout_height<span style="color:#67cdcc">=</span><span style="color:#7ec699">"wrap_content"</span>
        app:layout_constraintLeft_toLeftOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"parent"</span>
        app:layout_constraintRight_toLeftOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView2"</span>
        app:layout_constraintHorizontal_weight<span style="color:#67cdcc">=</span><span style="color:#7ec699">"2"</span> <span style="color:#67cdcc">/</span><span style="color:#67cdcc">></span>

    <span style="color:#67cdcc"><</span>TextView
        android:id<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView2"</span>
        android:layout_width<span style="color:#67cdcc">=</span><span style="color:#7ec699">"0dp"</span>
        android:layout_height<span style="color:#67cdcc">=</span><span style="color:#7ec699">"wrap_content"</span>
        app:layout_constraintLeft_toRightOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView1"</span>
        app:layout_constraintRight_toLeftOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView3"</span>
        app:layout_constraintRight_toRightOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"parent"</span>
        app:layout_constraintHorizontal_weight<span style="color:#67cdcc">=</span><span style="color:#7ec699">"3"</span> <span style="color:#67cdcc">/</span><span style="color:#67cdcc">></span>

    <span style="color:#67cdcc"><</span>TextView
        android:id<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView3"</span>
        android:layout_width<span style="color:#67cdcc">=</span><span style="color:#7ec699">"0dp"</span>
        android:layout_height<span style="color:#67cdcc">=</span><span style="color:#7ec699">"wrap_content"</span>
        app:layout_constraintLeft_toRightOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView2"</span>
        app:layout_constraintRight_toRightOf<span style="color:#67cdcc">=</span><span style="color:#7ec699">"parent"</span>
        app:layout_constraintHorizontal_weight<span style="color:#67cdcc">=</span><span style="color:#7ec699">"4"</span> <span style="color:#67cdcc">/</span><span style="color:#67cdcc">></span></code></span></span></span>
 
 
chinaStyel:用法
layout_constraintHorizontal_chainStyle來改變整條鏈的樣式。chains提供了3種樣式,分別是:
CHAIN_SPREAD —— 展開元素 (默認);
CHAIN_SPREAD_INSIDE —— 展開元素,但鏈的兩端貼近parent;
CHAIN_PACKED —— 鏈的元素將被打包在一起。

 
 
 
注意問題:
1:左邊和右邊要設置
2:左邊和右邊都要設置
3:左邊和右邊都要設置
<LinearLayout
    android:id="@+id/view_body"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/dp_22"
    app:layout_constraintHorizontal_weight="1.0"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/view_rate2"
    app:layout_constraintTop_toBottomOf="@id/view_line">

    <ImageView
        android:id="@+id/iv_body"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/icon_body" />

    <TextView
        android:id="@+id/tv_body"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="體質特徵" />

</LinearLayout>


<LinearLayout
    android:id="@+id/view_rate2"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintHorizontal_weight="1.0"
    app:layout_constraintLeft_toRightOf="@+id/view_body"
    app:layout_constraintRight_toLeftOf="@+id/view_oxy3"
    app:layout_constraintTop_toTopOf="@+id/view_body">

    <ImageView
        android:id="@+id/iv_rate2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/icon_body" />

    <TextView
        android:id="@+id/tv_rate2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="心率檢測" />

</LinearLayout>


<LinearLayout
    android:id="@+id/view_oxy3"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintHorizontal_weight="1.0"
    app:layout_constraintLeft_toRightOf="@+id/view_rate2"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="@+id/view_body">

    <ImageView
        android:id="@+id/iv_body3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/icon_body"
        android:src="@mipmap/icon_body" />

    <TextView
        android:id="@+id/tv_body3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="血液黏度" />

</LinearLayout>
 

 

Guideline輔助線:
感覺最重要的,對齊應該就是輔助線
看不到,可以用來切換比例
 
Barrier
 用法:在很多網頁的佈局上面用到
 
 
 
 
 
 
注意的問題:
margin:在約束佈局裏面有方向。
沒有約束,margin不會生效的。
 
但實際上控件在ConstraintLayout裏面要實現margin,必須先約束該控件在ConstraintLayout裏的位置
 
或者width的?
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-xml"><span style="color:#e2777a">android:layout_marginLeft不生效</span></code></span></span></span>
但是在ConstraintLayout裏,是不生效
<span style="color:#000000"><span style="color:#cccccc"><code class="language-xml"><span style="color:#e2777a"><span style="color:#cccccc"><</span>android.support.constraint.ConstraintLayout 
    android:layout_width<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>match_parent<span style="color:#cccccc">"</span></span>
    android:layout_height<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>match_parent<span style="color:#cccccc">"</span></span><span style="color:#cccccc">></span></span>

    <span style="color:#e2777a"><span style="color:#cccccc"><</span>TextView
        android:id<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>@+id/TextView1<span style="color:#cccccc">"</span></span>
        android:layout_width<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>wrap_content<span style="color:#cccccc">"</span></span>
        android:layout_height<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>wrap_content<span style="color:#cccccc">"</span></span>
        android:layout_marginLeft<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>10dp<span style="color:#cccccc">"</span></span>
        android:layout_marginTop<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>10dp<span style="color:#cccccc">"</span></span> <span style="color:#cccccc">/></span></span>

<span style="color:#e2777a"><span style="color:#cccccc"></</span>android.support.constraint.ConstraintLayout<span style="color:#cccccc">></span></span></code></span></span>
因爲沒有約束TextView1在佈局裏的位置。正確的寫法如下:
<span style="color:#000000"><span style="color:#cccccc"><code class="language-xml"><span style="color:#e2777a"><span style="color:#cccccc"><</span>android.support.constraint.ConstraintLayout 
    android:layout_width<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>match_parent<span style="color:#cccccc">"</span></span>
    android:layout_height<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>match_parent<span style="color:#cccccc">"</span></span><span style="color:#cccccc">></span></span>

    <span style="color:#e2777a"><span style="color:#cccccc"><</span>TextView
        android:id<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>@+id/TextView1<span style="color:#cccccc">"</span></span>
        android:layout_width<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>wrap_content<span style="color:#cccccc">"</span></span>
        android:layout_height<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>wrap_content<span style="color:#cccccc">"</span></span>
        android:layout_marginLeft<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>10dp<span style="color:#cccccc">"</span></span>
        android:layout_marginTop<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>10dp<span style="color:#cccccc">"</span></span> 
        app:layout_constraintLeft_toLeftOf<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>parent<span style="color:#cccccc">"</span></span>
        app:layout_constraintTop_toTopOf<span style="color:#7ec699"><span style="color:#cccccc">=</span><span style="color:#cccccc">"</span>parent<span style="color:#cccccc">"</span></span><span style="color:#cccccc">/></span></span>

<span style="color:#e2777a"><span style="color:#cccccc"></</span>android.support.constraint.ConstraintLayout<span style="color:#cccccc">></span></span></code></span></span>
 
 
 
位置偏移:
上面TextView1在水平居中後使用layout_marginLeft="100dp"向右偏移了100dp。除了這種偏移外,ConstraintLayout還提供了另外一種偏移的屬性:
layout_GoneMarginStart:用法
goneMargin
 
goneMargin主要用於約束的控件可見性被設置爲gone的時候使用的margin值,屬性如下:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

 
 

網頁:或者替換android的當百分比佈局用

<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-xml">layout_constraintVertical_bias:垂直乖離率(bias有道翻譯爲乖離率),也就是垂直偏移率。
layout_constraintHorizontal_bias:水平乖離率(bias有道翻譯爲乖離率),也就是水平偏移率。
layout_constraintHeight_percent:高度百分比,佔父類高度的百分比
layout_constraintWidth_percent:寬度百分比,佔父類寬度的百分比</code></span></span></span>
 
注意:
bias:也是要約束,如果沒有約束,bias也不會生效。
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-xml">layout_constraintHorizontal_bias</code></span></span></span>

 

 
分組功能

 
可以實現動畫的功能:比如:

ConstraintLayout+ConstraintSet實現動畫效果

 
其他:輔助功能
角度定位
<span style="color:#000000"><span style="color:#cccccc"><code class="language-objectivec"> app:layout_constraintCircle<span style="color:#67cdcc">=</span><span style="color:#7ec699">"@+id/TextView1"</span>
        app:layout_constraintCircleAngle<span style="color:#67cdcc">=</span><span style="color:#7ec699">"120"</span></code></span></span>
 
 
 
Ratio比例大小屬性
當你的父控件爲ConstraintLayout,可以利用這個屬性來控制當前View的寬高比。在利用這個屬性時,你必須指明一個方向上的大小爲0dp,另一個方向可指定爲明確的dp值也可以使用wrap_content這樣才能夠按照比例來爲你擺放
ratio:寬高比
應用:banner,或者視頻,始終保持在16:9
 
 
 
總結:
1、控件的寬、高都不可設置爲 match_parent,否則所有的約束失效
2、欲使設置的margin生效,須指定控件的約束對象。例如,欲使marginTop生效,須設定layout_constraintTop_toTopOf
3、欲使layout_constraintVertical_bias屬性生效,須設置上下約束。同樣欲使layout_constraintHorizontal_bias屬性生效,須設置左右約束
4、layout_marginLeft和layout_marginRight不起作用:控件左右都約束了parent,但有時左右margin不起作用,可能是因爲layout_width設置成了match_parent或者wrap_content,須改爲match_constraint(即0dp)纔會起作用
5、被Group持有的所有控件,其visiblity只能由Group決定
6、以當前佈局中不能準確知道高度的View爲標準,例如:在一個佈局中,左邊TextView的內容是固定的文字,右邊TextView的內容須根據具體業務進行動態設置,則其高度是不確定的,這種情況下高度約束均以右邊爲中心
7、自定義組合控件使用ConstraintLayout作爲佈局的根時,使用LinearLayout作爲自定義控件的父佈局時會造成自定義封裝的佈局展示不正確(寬高變形,與測量方式有關)。推薦使用FrameLayout作爲根佈局,同時固定高度
8、若ConstraintLayout不是根佈局,則其中的子控件的約束不能指定爲 parent,但可指定爲父控件ConstraintLayout的id
9、Guideline:
(1)layout_constraintGuide_percent屬性值可以爲負值,有時某些特殊的需求會用到
(2)對Guideline設置相對位置屬性是不生效的,因此當我們想要一個相對於某個view的Guideline時,約束佈局是不能滿足的。此時可以用一個不可見的View作爲Guideline的替代品來實現一些特殊佈局需求,如佈局重疊,這種方式可以彌補margin不能設置爲負值的不足
10、Chain:
(1)在chainStyle=spread時纔可以使用加權layout_constraintHorizontal_weight和layout_constraintVertical_weight 。
(2)注意Chain中的控件互相引用id的格式,是“@+id/button1”而非”@id/button1”。
(3)可以用Chain實現控件居中
11、注意View.inflate(getActivity(), R.layout.item, null)和LayoutInflater.from(getActivity()).inflate(R.layout.item, parent, false)區別,有時二者對ConstraintLayout佈局會有不同的影響
12、在ConstraintLayout中,控件除了可以設置layout_marginXXX外,還可以設置其依賴的控件gone之後的margin,即layout_goneMarginXXX。就是說,可以根據被依賴控件的visibility,設置兩種margin
————————————————
 
 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章