Search code examples
androidxmltextviewtruncation

Android TextView Truncation Priority or Compression Resistance


I'm laying out 3 views horizontally on the screen (fixed-size image and 2 single-line text views: leftTextView and rightTextView) and I'm trying to get the rightTextView to hug against the leftTextView, but in the event that the width of both labels would exceed the screen size, truncate the leftTextiew.

Example of desired functionality:

|img|leftText|rightText|                ||(end of screen)
|img|leftTextMedium|rightText|          ||
|img|leftTextTooLongSoTrunc...|rightText||

What's actually happening:

|img|leftText|rightText|                ||(end of screen)
|img|leftTextPrettyLongButNotHuge|rightT||
|img|leftTextWhichIsIncrediblyLongBlahBl||

Currently, if the size of both text views exceeds the view's width, the rightTextView ends up getting squished down to make room, even though I've set android:ellipsize="end" on the leftTextView.

Is there a way to make the leftTextView have a "truncation priority" that says it should truncate if it would cause other views to not fit? Or on the other side, can I set the rightTextView to have a "compression resistance" in order to keep it from being squished to make room for the leftTextView? Here's a sample of my XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/fixedWidthImage"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:id="@+id/leftTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@+id/fixedWidthImage"
        android:layout_toRightOf="@id/fixedWidthImage"
        android:maxLines="1"
        android:textSize="18sp"
        android:ellipsize="end" />

    <TextView
        android:id="@+id/rightTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@+id/leftTextView"
        android:layout_toRightOf="@+id/leftTextView"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:maxLines="1"
        android:textSize="12sp" />

</RelativeLayout>

Things I've tried:

  1. In the leftTextView, add a toStartOf / toLeftOf the rightTextView (crashes the app)
  2. Instead of aligning the rightTextView to the end/right of the leftTextView, flip it and align the leftTextView to the start/left of the rightTextView. This results in the rightTextView being anchored to the end of the screen instead of directly to the right of the leftTextView. Example of how this ends up looking:

    |img|leftText                 |rightText||
    |img|leftTextMedium           |rightText||
    |img|leftTextTooLongSoTrunc...|rightText||
    
  3. Even if I set android:minWidth="25dp" just to ensure at least part of the rightTextView is visible (which I don't want to do because this text length is variable) it still ends up compressing the width to make room for the leftTextView.

  4. Per Emanuel Moecklin's answer, I tried wrapping in a LinearLayout and setting the weight on the leftTextView. The result was visually identical to what I tried in #2.

Solution

  • You can archive this layout by TableLayout and shrinkColumns attribute.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        <!-- Row 1 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftText"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
    
        <!-- Row 2 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftTextPrettyLongButNotHuge"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
        <!-- Row 3 -->
        <TableLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:shrinkColumns="1">
    
            <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical">
    
                <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:text="leftTextWhichIsIncrediblyLongBlahBlahBlahBlah"/>
    
                <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:padding="4dp"
                        android:maxLines="1"
                        android:ellipsize="none"
                        android:text="rightText"/>
            </TableRow>
    
        </TableLayout>
    
    </LinearLayout>
    

    enter image description here