I am trying to make my TextView
has a dynamic width and an ImageView
pinned to the end of it, inside of a ConstraintLayout
. When the text is very long, I want to use an ellipsis and have the ImageView
pin to the view to the right of it.
Here is an example of what I am trying to achieve visually:
With my code, I am able to achieve the first image with thisIsShortText
but when I have long text, it looks bad, like this:
The TextView
and ImageView
just go off to the right to infinity. Can anyone help me fix this? This is the XML code I have. If you just put it into your Android Studio it will look like my images. Thank you:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="70dp">
<!-- This view does not move or change size. -->
<View
android:id="@+id/firstView"
android:layout_width="35dp"
android:layout_height="35dp"
android:background="@android:color/holo_red_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</View>
<!-- This view's width is dynamic and changes size based on it's text length.
If the length of text is too long to fit, it uses an ellipsize. -->
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="thisIsVeryLongTextThatIsTooLongAndIsLong"
android:textColor="@color/primary_text_dark"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/firstView"
app:layout_constraintTop_toTopOf="parent" />
<!-- This view is pinned to the end of textView. -->
<ImageView
android:id="@+id/imageview"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:background="@android:color/holo_purple"
android:src="@android:drawable/ic_dialog_info"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/textview"
app:layout_constraintTop_toTopOf="parent" />
<!-- This view does not move or change size. -->
<View
android:id="@+id/secondView"
android:layout_width="80dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@android:color/holo_blue_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/thirdView"
app:layout_constraintTop_toTopOf="parent" />
<!-- This view does not move or change size. -->
<View
android:id="@+id/thirdView"
android:layout_width="35dp"
android:layout_height="35dp"
android:background="@android:color/holo_orange_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can achieve that by adding the below to the TextView
:
imageview
)And constraint the end of the info imageview
to the start of the secondView
So, you need to add the following to the textview
:
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintEnd_toStartOf="@id/secondView"
And to the imageview
:
app:layout_constraintEnd_toStartOf="@+id/secondView"
Now the entire layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="70dp">
<!-- This view does not move or change size. -->
<View
android:id="@+id/firstView"
android:layout_width="35dp"
android:layout_height="35dp"
android:background="@android:color/holo_red_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</View>
<!-- This view's width is dynamic and changes size based on it's text length.
If the length of text is too long to fit, it uses an ellipsize. -->
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="thisIsVeryLongTextThatIsTooLongAndIsLong"
android:textColor="@color/primary_text_dark"
android:textSize="16sp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/imageview"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/firstView"
app:layout_constraintTop_toTopOf="parent" />
<!-- This view is pinned to the end of textView. -->
<ImageView
android:id="@+id/imageview"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@android:color/holo_purple"
android:src="@android:drawable/ic_dialog_info"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/secondView"
app:layout_constraintStart_toEndOf="@id/textview"
app:layout_constraintTop_toTopOf="parent" />
<!-- This view does not move or change size. -->
<View
android:id="@+id/secondView"
android:layout_width="80dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@android:color/holo_blue_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/thirdView"
app:layout_constraintTop_toTopOf="parent" />
<!-- This view does not move or change size. -->
<View
android:id="@+id/thirdView"
android:layout_width="35dp"
android:layout_height="35dp"
android:background="@android:color/holo_orange_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Preview: