简体   繁体   中英

Android layout how to horizontal align textView with dynamical width

Having 4 views A (TextView), B(icon), C(TextView), D (TextView) horizontally aligned next to each other.

B and D have fixed width. The text will be filled in the onBindView().

Their parent's width could be calculated based on the screen orientation.

It requires to show A as much as possible, and the C will consume the rest or up to its content width (if not enough space then show ellipsis).

And all A, B, C, D should left align the right edge of the previous one.

There are a few cases but these four cover most of them.

1. Parent width is enough for all

|-|AAAA|B|CCCCCCCC|DDD|--------------|-|

2. C is too large and have to show ellipses


|-|AAAAA|B|CCCCCCCCCCCCC...|DDD|-|

  3. A is large and have to show ellipse for C to be able to show

|-|AAAAAAA..........|B|CCCCCCCC|DDD|-|



4. the parent width is not enough for showing A and C completely, so A and C both show ellipses


|-|AAAAAAAAAAAAAA...|B|CCCCC...|DDD|-|

so the rule is to show A as much as possible, C shows either in full or with ellipses, in case with showing C's minWidth and still cannot show the A in full then show A with ellipsis.

Tried LinearLayout, RelativeLayout and ConstraintLayout and cant get the desired result.

this has two maxWidth for A and C, the problem is if either A or C is too small the other one may still show ellipsis without using all available space.

   <LinearLayout
        android:id="@+id/container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:orientation="horizontal"
        >


        <TextView
            android:id="@+id/a_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxWidth="130dp"
            android:maxLines="1"
            android:textSize="16sp"
            android:textStyle="bold"
            tools:text="ee" />

        <ImageView
            android:id="@+id/b_checked"
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:layout_marginStart="3dp"
            android:layout_marginEnd="8dp"
            android:baselineAlignBottom="true"
            app:srcCompat="@drawable/checked" />

        <TextView
            android:id="@+id/c_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:ellipsize="end"
            android:maxWidth="150dp"
            android:maxLines="1"
            tools:text="aasdasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa" />

        <TextView
            android:id="@+id/d_time"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_gravity="left"
            tools:text="30 Nov 18"
            />

    </LinearLayout>

If do it in a derived view and override the onMeasure(), the calculation is not straight forward and the A, C width may not immediately available.

How to do it just in layout xml, or is it possible?

I'm not sure if this meets your requirements, but this is my attempt using ConstraintLayout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <TextView
        android:id="@+id/one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#eee"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="something very very very very very long"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/two"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="fixed"
        app:layout_constraintBaseline_toBaselineOf="@id/one"
        app:layout_constraintLeft_toRightOf="@id/one"
        app:layout_constraintRight_toLeftOf="@id/three"/>

    <TextView
        android:id="@+id/three"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#eee"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="this is pretty short"
        app:layout_constraintBaseline_toBaselineOf="@id/one"
        app:layout_constraintLeft_toRightOf="@id/two"
        app:layout_constraintRight_toLeftOf="@id/four"
        app:layout_constraintWidth_default="wrap"/>

    <TextView
        android:id="@+id/four"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="fixed"
        app:layout_constraintBaseline_toBaselineOf="@id/one"
        app:layout_constraintLeft_toRightOf="@id/three"
        app:layout_constraintRight_toRightOf="parent"/>


</androidx.constraintlayout.widget.ConstraintLayout>

The important parts here are that the first "stretchable" view uses wrap_content while the second uses 0dp plus app:layout_constraintWidth_default="wrap" . This will give the space to the first view at a higher priority than the second view, but will allow both to grow and shrink.

The only problem I've found is that, when the first view's text is very long, it can push the other views on top of each other. This could potentially be solved by adding a maximum width to the first view:

app:layout_constraintWidth_max="256dp"

Some screenshots:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM