Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Layout: How to keep right-most text element and ellipsize left-most text element as it grows?

I have a LinearLayout which contains two TextViews. Let the first TextView's text be "short text" and the 2nd TextView's text be "(s)".

<LinearLayout
     android:layout_width="0dp"
     android:layout_weight="1"
     android:layout_height="match_parent"
     android:orientation="horizontal">

     <TextView
            android:id="@+id/variable-size"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:ellipsize="middle"
            android:lines="1"
            android:singleLine="true"
            android:text="short text"/>

        <TextView
            android:id="@+id/fixed-size"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:ellipsize="none"
            android:lines="1"
            android:singleLine="true"
            android:text="(s)" />

</LinearLayout>

I want the LinearLayout to appear to the user thus:

[[short text][(s)]____________]

where ____ means empty view.

Now if I put a slightly longer string into the first TextView, I want to see this:

[[slightly longer text][(s)]__]

and if I put a much longer string into the first TextView, I want to see this:

[[really long ...ng text][(s)]]

But I can't seem to find a way to keep the first TextView from crowding out the second TextView altogether, like so:

[[really long lo... long text]]

How do I get the behavior I am looking for?

like image 685
Patrick Brennan Avatar asked Jan 08 '23 13:01

Patrick Brennan


1 Answers

The base of the answer to your question is this:

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/variable-size"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:ellipsize="middle"
        android:lines="1"
        android:singleLine="true"
        android:text="short text" />

    <TextView
        android:id="@+id/fixed-size"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:ellipsize="none"
        android:lines="1"
        android:singleLine="true"
        android:text="(s)" />

</LinearLayout>

BUT... bare in mind that I changed the width of your LinearLayout from:

android:layout_width="0dp"
android:layout_weight="1"

to

android:layout_width="wrap_content"

and that's a really important part of the answer.

The code I presented works like this:

[[short text][(s)]]
[[slightly longer text][(s)]]
[[really long ...ng text][(s)]]

It manages the ellipsizing correctly, but cannot introduce the "empty view" (____). If I didn't change the LinearLayout's layout_width, the ellipsizing would work correctly ((s) wouldn't be pushed off the screen), but the text alignment wouldn`t be correct. It would look like this:

[[short text            ][(s)]]
[[slightly longer text  ][(s)]]
[[really long ...ng text][(s)]]

So if the "empty view" is a need for you, you will need to implement it (for example) with nesting your LinearLayout inside another one (and this time "empty view" is gonna be an actual View). Like so:

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/variable-size"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:ellipsize="middle"
            android:lines="1"
            android:singleLine="true"
            android:text="short text" />

        <TextView
            android:id="@+id/fixed-size"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:ellipsize="none"
            android:lines="1"
            android:singleLine="true"
            android:text="(s)" />

    </LinearLayout>

    <View
        android:id="@+id/empty_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

This will give you the following behaviour:

[[[short text][(s)]]____________]
[[[slightly longer text][(s)]]__]
[[[really long ...ng text][(s)]]]
like image 66
Bartek Lipinski Avatar answered May 08 '23 16:05

Bartek Lipinski