先来看下想要的效果:
左文右图,标题最多显示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,让它自己拉伸开。