Search code examples
androidlayouttruncatespacefill

Android layout space-filling problem


I'm having real difficulty coming up with a layout which works. I have a view which fills the width of the screen. It contains three sub-views:

  1. Some text
  2. A number in parentheses after the main text
  3. A button

The button is right-aligned, and the text items are left-aligned one after the other, as shown:

| Some heading text (n)             [button]  |

The problem is controlling what happens when the text is too long. I want it like this, so that the number is always visible just to the right of the main text. The main text should be truncated if needed so the other two views remain visible.

| Some very very long headin... (n) [button]  |

The closest I've got which succesfully truncates the main text results in the (n) always being right-aligned next to the button even when the main text is short enough to fit. That's not what I want.

How would you approach this?

I'm not posting any of my current XML yet, lest it prejudice anyone's suggestions.


Solution

  • I do not believe there's any xml layout for that. My guess is that you will need to extend TextView and measure the text length inside onDraw(...), adjusting the text accordingly through some iteration (i.e., removing one character at a time until the text fits the canvas)

    I just found another question that is quite similar to yours: Ellipsize only a section in a TextView . No other answer than ellipsize in the middle.


    Another thoughts:

    I'm wondering if it would work to have one textview with the main text (ellipsize left, wrap_content) and another with the number in the parenthesis (wrap_content), both inside an horizontal linear layout. That layout would be inside a relative layout and layout_toLeftOf the button, which would be wrap_content, layout_alignParentRight.

    Does it make any sense? I don't have Eclipse now to test it myself. Not sure if the (n) textview would be lost behind the button or not with a long text.

    Alternatively (and less interesting), you can setup one single relative layout with the two textviews all layout_toRightOf and the button aligned to the right (layout_alignParentRight) and set the max witdth ot the first textview (android:maxWidth). You would need to set up different layouts for different screens, though.


    An example with a fixed max width that will work as required:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="click me"
        android:id="@+id/bt1"
        android:layout_alignParentRight="true"
        />    
        <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="short text"
        android:lines="1"
        android:ellipsize="end"
        android:id="@+id/t1"
        android:layout_alignParentLeft="true"
        />
        <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="(n)"
        android:lines="1"
        android:id="@+id/n1"
        android:layout_toRightOf="@id/t1"
        />
        <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="click me"
        android:id="@+id/bt2"
        android:layout_below="@id/bt1"
        android:layout_alignParentRight="true"
        />    
        <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="very long text that will not fit in any layout, regardless of the size of the screen"
        android:lines="1"
        android:ellipsize="end"
        android:id="@+id/t2"
        android:layout_below="@id/bt1"
        android:layout_alignParentLeft="true"
        android:maxWidth="220dp"
        />
        <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="(n)"
        android:lines="1"
        android:id="@+id/n2"
        android:layout_below="@id/bt1"
        android:layout_toRightOf="@id/t2"
        />
    </RelativeLayout>