天天看點

ConstraintLayout限制布局——實作左文右圖效果

先來看下想要的效果:

左文右圖,标題最多顯示2行,時間和圖檔底部對齊

ConstraintLayout限制布局——實作左文右圖效果

1、問題說明: 在這個布局中,左邊的文字和時間是一個整體,右邊的圖檔是一個整體,讓圖檔隻位于文字右側或者時間右側都是不對的。

(1)圖檔位于文字右側:當文字較少時,時間可能會遮擋圖檔。

(2)圖檔位于時間右側:當文字較多時,文字可能會遮擋圖檔。

ConstraintLayout限制布局——實作左文右圖效果

對應代碼如下:

<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>
           

效果如圖:

ConstraintLayout限制布局——實作左文右圖效果

2、問題說明: 解決了問題1,又出現一個問題,當标題過長時,圖檔被擠出界面了,而我們想要的是,圖檔固定在右邊,标題能自适應,當文字到達右邊極限時,自動換行,而不會把圖檔擠出去。

ConstraintLayout限制布局——實作左文右圖效果

解決方法: 換個思路想想,既然圖檔需要固定,那可以把設定屏障的方法反過來,圖檔在右邊,為圖檔設定屏障,屏障在圖檔的左邊,标題和時間限制在屏障左側

<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>
           

效果如圖:

ConstraintLayout限制布局——實作左文右圖效果

3、問題說明: 解決了問題2,又出現第3個問題,真是一坑接一坑啊,标題和時間沒有居左顯示,标題過長直接出界面了,沒有自動換行。

ConstraintLayout限制布局——實作左文右圖效果

解決方法: 為了不讓标題出界面,可以設定标題左邊在父布局左邊

為标題布局加上一句代碼:

app:layout_constraintLeft_toLeftOf="parent"
           

效果如圖:

ConstraintLayout限制布局——實作左文右圖效果

我們會發現屏障失效了,問題并沒有得到解決,我們再來試試

将标題控件的寬度設定為0dp:

android:layout_width="0dp"
           

效果如圖:

ConstraintLayout限制布局——實作左文右圖效果

标題終于自動換行了,并且撐滿了剩下的整個空間,我們再給時間控件加上這兩行代碼:

android:layout_width="0dp"
app:layout_constraintLeft_toLeftOf="parent"
           

好了,最終效果搞定!!

ConstraintLayout限制布局——實作左文右圖效果

大家會問: 既然控件的左右側都做了限制,那這裡控件的寬度可以設定為 match_parent 啊,不就自己撐滿了嗎?

ConstraintLayout限制布局——實作左文右圖效果

實際效果卻不是這樣,我們會發現屏障失效了,控件直接填充了父布局。

這是因為在限制布局裡,match_parent是填充滿父布局,盡管右側有屏障限制,但是 match_parent 會覆寫屏障的功能。是以最好設定為0dp,讓它自己拉伸開。

上一篇: Java.20
下一篇: Java.19