如何防止一个具有可变尺寸的TextView将一个ImageView“推出”屏幕外?

8
在约束布局中,我有一个文本视图和一个相邻的图片视图:enter image description here 但有时文本视图中的文本可能非常长,有时会跨越多行。在这些情况下,图像视图会被推出视图之外:enter image description here 即使在图像视图和视图容器之间添加了约束,图像视图也会被推到视图之外。
目标是始终将图像放在文本旁边,如果文本增大,则图像开始向侧面推移,只要不超出视图范围。当它接触视图的边界时,应该停留在那里,而文本则换行到下一行。
此代码块仅显示第二张图片的情况:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView" android:layout_marginTop="8dp"
        app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp"
        tools:text="This is a cat with a lot more text next to it so pay attention  "/>
<ImageView
        android:layout_width="30dp"
        android:layout_height="30dp" tools:srcCompat="@tools:sample/avatars[3]"
        android:id="@+id/imageView"
        app:layout_constraintStart_toEndOf="@+id/textView" android:layout_marginStart="8dp"
        android:layout_marginTop="8dp" app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0"/>

</androidx.constraintlayout.widget.ConstraintLayout>

我尝试使用屏障和指南,但它们对这种情况真的没有用。 Textview需要是wrap_content,因为它的大小是可变的,并且最好使用约束布局,这就是为什么我没有使用其他布局的原因。链在这里也不起作用。
2个回答

25

您可以使用偏移量为0的紧凑链来使其左对齐,然后为两个视图设置app:layout_constrainedWidth="true",以便在包装内容时尊重它们的约束。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:text="Text goes here"
        android:textSize="24sp"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toStartOf="@id/image"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/textView"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@tools:sample/avatars" />

</android.support.constraint.ConstraintLayout>

使用约束布局2.1.0时,我不得不将TextView的app:layout_constrainedWidth属性从"true"更改为"wrap_content_constrained"。 - xklakoux

0
问题在于您设置了textview的wrap_content。这样做将让textview决定自己的宽度,忽略布局约束,如边距。
您需要将宽度设置为0dp,在约束布局中被解释为match_constraint,它允许布局决定textview的宽度,这意味着textview将在应用边距和其他布局约束后被赋予尽可能多的宽度。
现在,为了达到您想要的效果,首先从两个视图中删除所有约束。选择它们两个,然后右键单击并从选项菜单中选择链选项。然后将它们水平排列。这将形成一个链。 为什么我们需要链? 因为您希望imageview位于textview的右侧,而textview位于imageview的左侧,这种双向约束无法添加,因为TextView不会绘制,直到ImageView绘制完成,而ImageView正在等待TextView绘制。 链将帮助您解决这个问题。

谢谢你的回复!在这种情况下,我所缺少的是属性layout_constrainedWidth。事实上,我需要使用chain,但仅仅使用它是不够的。 - Artenes Nogueira
layout_constrainedWidth和将layout_width设置为0dp的效果是一样的,所以两个答案都是相同的。我当时正在手机上打字,所以发布有点晚,但无论如何,很高兴它能够正常工作 :) - Zohaib Amir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接