Android MultiLine Text Wrapping

Advertisements

I am in the process of building my first Android app and running into a weird problem where text wrapping doesn’t seem to work as one would expect. The XML layout is a RelativeLayout because it’s a list item template for a RecyclerView. Inside the row template there are three TextView objects – the intention is the first two are on one line and the third is on a separate line. Here is the XML structure:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <!-- should be ~85% of view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:layout_margin="6dp"
        android:background="@drawable/list_item_border"
        android:padding="6dp">

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

            <!-- this text should wrap when the content is too big, but it
                 only does if I set a maxWidth which feels hacky since that
                 isn't a great multi-device solution -->
                 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/txDisplayName"
                tools:text="** I should wrap when I hit the max available space within my container **"
                android:textStyle="bold"
                android:elegantTextHeight="true"
                android:singleLine="false"
                android:minLines="1"
                android:maxLines="99"
                android:lines="3"
                android:textSize="16sp" />

            <!-- secondary item on this "row" - should always be below the TextView above -->
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:id="@+id/txSKU"
                android:textStyle="italic"
                android:textSize="18dp"
                tools:text="00000-0000-00" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:minWidth="30sp"
            android:gravity="right">

            <!-- should be ~15% of total view -->
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:textSize="18dp"
                android:id="@+id/tvReceivingSummary"
                tools:text="00/00" />

        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

For reference, the @drawable/list_item_border just adds a small border around the entire row. It’s defined as:

<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <stroke
        android:width="2dp"
        android:color="@color/prx_blue" />

    <corners android:radius="2dp" />

</shape>

The end goal is something like this (full screen width):

==================================================================
| Potentially long text that should always wrap when |     00/00 |
| the text gets too long. The values come from an    |           |
| API so it's not controllable text (meaning I can't |           |
| easily add "\n" because I wouldn't know where to   |           |
| separate it out.                                   |           |
==================================================================
| This is the second row - no need to wrap                       |
==================================================================

I’ve tried various combinations of RelativeLayout, ConstraintLayout and TableLayout, but it seems like I can either get text to wrap (but overlap itself), or I can get it to
not overlap, but it doesn’t wrap and pushes the 00/00 off the view so it’s not visible.

Any suggestions? I know I have to be close and have looked at multiple SO posts, but being new to this I’m kind of spinning my wheels at this point and hoping someone can assist.

>Solution :

are you familiar with android:layout_weight? thats an attribute for childs of LinearLayout and seems perfect fit for your case

just use android:layout_weight="85" and android:layout_weight="15" for your child linears, layout_width="0" for both (as parent LinearLayout with orientation="horizontal" will stretch them according to weights)

btw. there is also related param weightSum

btw. your root RelativeLayout have wrap_content for dimens and one and only child – "main" LinearLayout – have match_parent. thats pretty unefficient for drawing… especially because your RelativeLayout isn’t needed at all… remove it, before that move xmlns attributes to "main" LinearLayout and set layout_height="wrap_content" for better fitting and measuring by RecyclerView. Generally: less nested XMLs/layers => better performance

Leave a ReplyCancel reply