Reputation: 11035
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?
Upvotes: 0
Views: 470
Reputation: 54244
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:
Upvotes: 1