Home > Mobile >  Android MultiLine Text Wrapping
Android MultiLine Text Wrapping

Time:12-22

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.

CodePudding user response:

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

  • Related