0

I'm trying have an image to the right of a TextView with a single line. When the text is short it works fine. The problem is when the text is too big and is truncated. The text fills the LinearLayout and the image is off screen

Short text:
short text

Long text:
long text

The 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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="32sp"
            android:ellipsize="end"
            android:maxLines="1"
            tools:text="Lorem ipsum dolor sit amet, consectetur"/>

        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/ivInfectedDevOtherInfoIcon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginStart="8dp"
            app:layout_constraintTop_toTopOf="@+id/ivInfectedDevOtherName"
            app:layout_constraintStart_toEndOf="@+id/ivInfectedDevOtherName"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0"
            app:srcCompat="@drawable/ic_tv" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

When the text is long how can I make the Image dock to the right so that it does not overlap?

Raimundo
  • 605
  • 7
  • 21

3 Answers3

1

Edit 1: From the comments:

This works when the text is long and is truncated. When the text is short the image stays docked at the right and there is a bigger gap then the intended 8dp between the two element

So the behavior you're looking for won't work unless the view is plugged right into the TextView which will measure the current width & truncates when the end is reached on the drawable & not text. So you can create such component or use drawableEnd or drawableEndCompat.

With drawableEndCompat Your layout would look like this(You can remove LinearLayout IMO):

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/tvText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="1"
            android:textSize="32sp"
            app:drawableEndCompat="@drawable/ic_add"
            android:text="Lorem cd" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

If you want to have a click on drawableEndCompat then you can look at answers on SO like this: Implement onClick only for a TextView compound drawable

Example:

@SuppressLint("ClickableViewAccessibility")
    private void setOnEndClickListener() {
        TextView txtview = (TextView) findViewById(R.id.tvText);
        txtview.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    if (event.getRawX() >= txtview.getRight() - txtview.getTotalPaddingRight()) {
                        Log.d("MG-onClick", "Drawable Clicked");
                        return true;
                    }
                }
                return true;
            }
        });
    }

Old Answer:

Add layout_weight=1 & layout_width="0dp" to your TextView.

So it would look like this:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textSize="32sp"
            android:ellipsize="end"
            android:maxLines="1"
            android:layout_weight="1"
            tools:text="Lorem ipsum dolor sit amet, consectetur"/>

        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/ivInfectedDevOtherInfoIcon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginStart="8dp"
            app:layout_constraintTop_toTopOf="@+id/ivInfectedDevOtherName"
            app:layout_constraintStart_toEndOf="@+id/ivInfectedDevOtherName"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0"
            app:srcCompat="@drawable/ic_add" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Mayur Gajra
  • 8,285
  • 6
  • 25
  • 41
  • This works when the text is long and is truncated. When the text is short the image stays docked at the right and there is a bigger gap then the intended 8dp between the two elements – Raimundo May 25 '21 at 16:49
  • @Raimundo Try the updated answer. See if it works for you. – Mayur Gajra May 26 '21 at 04:27
  • This ways works. But @MariosP answer also works and it suits better for my needs. Thanks. – Raimundo May 26 '21 at 13:13
1

Simply make the below changes to your xml layout:

1.In LinearLayout add:

android:layout_width="wrap_content"
app:layout_constraintHorizontal_bias="0"

2.In TextView add:

android:layout_weight="1"

3.In AppCompatImageView add:

android:layout_weight="0"

Final xml layout will be like below:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="32sp"
            android:ellipsize="end"
            android:layout_weight="1"
            android:maxLines="1"
            tools:text="Lorem ipsum dolor sit amet, consectetur "/>

        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/ivInfectedDevOtherInfoIcon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginStart="8dp"
            android:layout_weight="0"
            app:layout_constraintTop_toTopOf="@+id/ivInfectedDevOtherName"
            app:layout_constraintStart_toEndOf="@+id/ivInfectedDevOtherName"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0"
            app:srcCompat="@drawable/ic_tv" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Result for Long Text:

long_text

Result for Small Text:

small_text

MariosP
  • 8,300
  • 1
  • 9
  • 30
0

Try this way...

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_weight="8"
        android:layout_height="wrap_content"
        android:textSize="32sp"
        android:ellipsize="end"
        android:maxLines="1"
        tools:text="Lorem ipsum dolor sit amet, consectetur"/>

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/ivInfectedDevOtherInfoIcon"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="40dp"
        android:layout_marginStart="8dp"
        app:layout_constraintTop_toTopOf="@+id/ivInfectedDevOtherName"
        app:layout_constraintStart_toEndOf="@+id/ivInfectedDevOtherName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0"
        app:srcCompat="@drawable/ic_tv" />

  </LinearLayout>
  </androidx.constraintlayout.widget.ConstraintLayout>
Tausif
  • 778
  • 1
  • 5
  • 14
  • When the text is short the image stays docked at the right and there is a bigger gap then the intended 8dp between the two elements. – Raimundo May 25 '21 at 16:53
  • Still doesn't work. When the text is short the image stays docked to the right and it does not have the size of 40dp. `android:layout_weight` does not seem to be the way to solve this. – Raimundo May 25 '21 at 17:08
  • You can add attribute android:maxLength="20" in your textView Widget – Tausif May 25 '21 at 17:44
  • But then there is some space not used to the right. And this way won't work on all screens sizes and densities. – Raimundo May 25 '21 at 19:05