2

I have a ConstraintLayout which contains a TextView that has an small image at the end of the text. This issue I'm having is that long text is not wrapping. If I fix the constraints on the TextView so that long text wraps the image at the end goes to the end of the screen:

Screenshot:

enter image description here

If I add app:layout_constraintEnd_toEndOf="parent" to the TextView the long text wraps but the image at the end doesn't:

enter image description here

Code:

<?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="wrap_content"
    android:padding="10dp"
    android:layout_marginBottom="20dp"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/subscription_row_item_thumb"
        android:layout_width="65dp"
        android:layout_height="65dp"
        android:scaleType="centerInside"
        android:background="@drawable/all_circle_white_bg"
        android:padding="1dp"
        android:foreground="?android:attr/selectableItemBackground"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <ImageView
        android:id="@+id/subscription_row_item_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:layout_marginTop="15dp"
        app:layout_constraintTop_toBottomOf="@id/subscription_row_item_thumb"
        app:layout_constraintStart_toStartOf="@id/subscription_row_item_thumb"
        app:layout_constraintEnd_toEndOf="@id/subscription_row_item_thumb"/>

     <TextView
        android:id="@+id/subscription_row_item_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:breakStrategy="simple"
        android:layout_marginStart="15dp"
        android:textSize="16sp"
        app:layout_constrainedWidth="true"
        app:drawableEndCompat="@drawable/ic_action_open_episode_list"
        android:drawablePadding="10dp"
        app:layout_constraintTop_toTopOf="@id/subscription_row_item_thumb"
        app:layout_constraintBottom_toBottomOf="@id/subscription_row_item_thumb"
        app:layout_constraintStart_toEndOf="@id/subscription_row_item_thumb"
        app:layout_constraintEnd_toEndOf="parent"/>

    <TextView
        android:id="@+id/subscription_row_item_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:breakStrategy="simple"
        android:layout_marginTop="5dp"
        android:textSize="14sp"
        android:textColor="#A1A0A0"
        app:layout_constraintTop_toBottomOf="@id/subscription_row_item_title"
        app:layout_constraintStart_toStartOf="@id/subscription_row_item_title"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Zain
  • 37,492
  • 7
  • 60
  • 84
Kris B
  • 3,436
  • 9
  • 64
  • 106

3 Answers3

5

To fix this you need to:

  1. wrap_content the width to keep the drawableEnd stick to the end of the text, and to avoid sticking it to the end due to the app:layout_constraintEnd_toEndOf="parent"
  2. Set the app:layout_constraintHorizontal_bias="0" in order to bias the TextView to the start

When the TextView content expands, the app:layout_constraintEnd_toEndOf="parent" will be effective

Applying those to the TextView:

 <TextView
    android:id="@+id/subscription_row_item_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:breakStrategy="simple"
    android:layout_marginStart="15dp"
    android:textSize="16sp"
    app:layout_constrainedWidth="true"
    app:layout_constraintHorizontal_bias="0"
    app:drawableEndCompat="@drawable/ic_action_open_episode_list"
    android:drawablePadding="10dp"
    app:layout_constraintTop_toTopOf="@id/subscription_row_item_thumb"
    app:layout_constraintBottom_toBottomOf="@id/subscription_row_item_thumb"
    app:layout_constraintStart_toEndOf="@id/subscription_row_item_thumb"
    app:layout_constraintEnd_toEndOf="parent"/>

enter image description here

Zain
  • 37,492
  • 7
  • 60
  • 84
  • 1
    But I want the icon to wrap with the text. so it is always to the direct right of the last word. So in your top screenshot the mail icon would be to the right of the word "text" on the second line. I'm thinking it is either not possible or I'm thinking of this wrong. – Kris B Sep 27 '21 at 02:52
  • This is not the behavior of drawableEnd. As its name implies it is a drawable at the end of the textView box.. Not the text itself.. You need to add a drawable within the text as a content. And this has nothing to do with the ConstraintLayout – Zain Sep 27 '21 at 03:20
  • @KrisB [This](https://stackoverflow.com/questions/68068263/android-using-icon-in-text-of-textview/68070920#68070920) could help you – Zain Sep 27 '21 at 10:29
  • I see. I guess I was confused. That link you sent helped. I need to add the icon to the text itself. Thanks! – Kris B Sep 28 '21 at 20:11
0

Maybe that will help

<?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="wrap_content"
    android:padding="10dp"
    android:layout_marginBottom="20dp"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/subscription_row_item_thumb"
        android:layout_width="65dp"
        android:layout_height="65dp"
        android:scaleType="centerInside"
        android:background="@drawable/all_circle_white_bg"
        android:padding="1dp"
        android:foreground="?android:attr/selectableItemBackground"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <ImageView
        android:id="@+id/subscription_row_item_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:layout_marginTop="15dp"
        app:layout_constraintTop_toBottomOf="@id/subscription_row_item_thumb"
        app:layout_constraintStart_toStartOf="@id/subscription_row_item_thumb"
        app:layout_constraintEnd_toEndOf="@id/subscription_row_item_thumb"
        />

    <LinearLayout
        android:id="@+id/layout_item_title"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:drawablePadding="10dp"
        app:layout_constraintTop_toTopOf="@id/subscription_row_item_thumb"
        app:layout_constraintBottom_toBottomOf="@id/subscription_row_item_thumb"
        app:layout_constraintStart_toEndOf="@id/subscription_row_item_thumb"
        app:layout_constraintEnd_toEndOf="parent">

        <TextView
            android:id="@+id/subscription_row_item_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:breakStrategy="simple"
            android:layout_marginStart="15dp"
            android:textSize="16sp"
            app:layout_constrainedWidth="true"
            app:drawableEndCompat="@drawable/ic_action_open_episode_list"/>

    </LinearLayout>

    <TextView
        android:id="@+id/subscription_row_item_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:breakStrategy="simple"
        android:layout_marginTop="5dp"
        android:layout_marginStart="15dp"
        android:textSize="14sp"
        android:textColor="#A1A0A0"
        app:layout_constraintTop_toBottomOf="@id/layout_item_title"
        app:layout_constraintStart_toStartOf="@id/layout_item_title"/>

</androidx.constraintlayout.widget.ConstraintLayout>
MNarcis
  • 1
  • 1
  • 5
  • Yes, I thought about that put I was hoping there was a more elegant solution. I mean it's not that long of text. – Kris B Sep 24 '21 at 14:26
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 24 '21 at 17:58
0

The location of drawables associated with a TextView apply to the start, top, end and bottom of the TextView itself and not the text contained within. This is the behavior that you see.

You can use an ImageSpan to associate a drawable with the end of the text but this will have to be done programmatically.

    val image = ContextCompat.getDrawable(this, R.drawable.ic_baseline_open_in_new_24)!!
    val imageSize = textView.lineHeight / 2
    image.updateBounds(bottom = imageSize, right = imageSize)
    val imageSpan = ImageSpan(
        image,
        DynamicDrawableSpan.ALIGN_BASELINE
    )
    val spannable = SpannableString("${textView.text} ")
    spannable.setSpan(
        imageSpan, spannable.length - 1, spannable.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE
    )
    textView.text = spannable

enter image description here

Here the icon is positioned at the end of the text and replaces the final space character.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131