先來看下想要的效果:
左文右圖,标題最多顯示2行,時間和圖檔底部對齊
1、問題說明: 在這個布局中,左邊的文字和時間是一個整體,右邊的圖檔是一個整體,讓圖檔隻位于文字右側或者時間右側都是不對的。
(1)圖檔位于文字右側:當文字較少時,時間可能會遮擋圖檔。
(2)圖檔位于時間右側:當文字較多時,文字可能會遮擋圖檔。
對應代碼如下:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
app:layout_constraintVertical_bias="0.9"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="70dp"
android:scaleType="centerCrop"
android:src="@drawable/test_img"
app:layout_constraintLeft_toRightOf="@+id/time"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标題标題标題标題标題标題題标題标題标題标題标題題标題标題"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2018-12-25 12:32"
app:layout_constraintBottom_toBottomOf="@+id/img" />
</android.support.constraint.ConstraintLayout>
解決方法: 針對這個問題,ConstraintLayout 中有個 Barrier(屏障)的概念。即給多個控件設定屏障,保證其他控件在這個屏障的另一側。由此,可以在左文和右圖之間設定屏障。
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="title, time" />
屬性說明:
app:barrierDirection 用來設定針對哪幾個控件的屏障的位置(上下左右)
app:constraint_referenced_ids 用來設定針對哪幾個控件設定屏障
這裡為标題和時間設定屏障,然後屏障的位置在标題和時間的右側。
上述代碼改為:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
app:layout_constraintVertical_bias="0.9"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="70dp"
android:scaleType="centerCrop"
android:src="@drawable/test_img"
app:layout_constraintLeft_toRightOf="@+id/barrier" />
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="title, time" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标題标題标題标題标題标題标題标題标題題标題标題"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2018-12-25 12:32"
app:layout_constraintBottom_toBottomOf="@+id/img" />
</android.support.constraint.ConstraintLayout>
效果如圖:
2、問題說明: 解決了問題1,又出現一個問題,當标題過長時,圖檔被擠出界面了,而我們想要的是,圖檔固定在右邊,标題能自适應,當文字到達右邊極限時,自動換行,而不會把圖檔擠出去。
解決方法: 換個思路想想,既然圖檔需要固定,那可以把設定屏障的方法反過來,圖檔在右邊,為圖檔設定屏障,屏障在圖檔的左邊,标題和時間限制在屏障左側
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="left"
app:constraint_referenced_ids="img" />
詳細代碼如下;
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
app:layout_constraintVertical_bias="0.9"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="70dp"
android:scaleType="centerCrop"
android:src="@drawable/test_img"
app:layout_constraintRight_toRightOf="parent" />
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="left"
app:constraint_referenced_ids="img" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标題标題标題标題标題标題标題标題标題标題題标題标題"
android:maxLines="2"
android:ellipsize="end"
android:layout_marginRight="10dp"
app:layout_constraintRight_toLeftOf="@+id/barrier"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="2018-12-25 12:32"
android:layout_marginRight="10dp"
app:layout_constraintRight_toLeftOf="@+id/barrier"
app:layout_constraintBottom_toBottomOf="@+id/img" />
</android.support.constraint.ConstraintLayout>
效果如圖:
3、問題說明: 解決了問題2,又出現第3個問題,真是一坑接一坑啊,标題和時間沒有居左顯示,标題過長直接出界面了,沒有自動換行。
解決方法: 為了不讓标題出界面,可以設定标題左邊在父布局左邊
為标題布局加上一句代碼:
app:layout_constraintLeft_toLeftOf="parent"
效果如圖:
我們會發現屏障失效了,問題并沒有得到解決,我們再來試試
将标題控件的寬度設定為0dp:
android:layout_width="0dp"
效果如圖:
标題終于自動換行了,并且撐滿了剩下的整個空間,我們再給時間控件加上這兩行代碼:
android:layout_width="0dp"
app:layout_constraintLeft_toLeftOf="parent"
好了,最終效果搞定!!
大家會問: 既然控件的左右側都做了限制,那這裡控件的寬度可以設定為 match_parent 啊,不就自己撐滿了嗎?
實際效果卻不是這樣,我們會發現屏障失效了,控件直接填充了父布局。
這是因為在限制布局裡,match_parent是填充滿父布局,盡管右側有屏障限制,但是 match_parent 會覆寫屏障的功能。是以最好設定為0dp,讓它自己拉伸開。