Search code examples
androidandroid-layoutandroid-constraintlayout

ConstraintLayout 2 TextView first one ellipsize


UPDATE

I achieved this behavior with following things:

txtFullName

android:layout_width="0dp"
app:layout_constraintWidth_default="wrap"

btnFollow and btnUnfollow

android:layout_width="0dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintWidth_default="wrap"
app:layout_constraintWidth_min="wrap"

ORIGINAL QUESTION

I have an XML layout which is parent layout is ConstraintLayout and inside

       -- txtFullName -- (btnFollow | btnUnfollow ) --       
Avatar ----------------------------------------------- btnPrimaryAction
       -- txtTitle -----------------------------------

I want this:

Long txtFullname okay

But I got this with my xml

Long txtFullName not okay

When txtFullName is long, it is overlapping btnFollow or btnUnfollow and these buttons are not showing on screen. I want txtFullName to be ellipsize when it is long. I tried to use ConstraintLayout's Flow but it didn't work well too.

My layout constraints can be shown below.

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/imgAvatar"
        android:layout_width="56dp"
        android:layout_height="56dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@tools:sample/avatars" />

    <TextView
        android:id="@+id/txtFullName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="2dp"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="?attr/textColorMarineBlue"
        app:layout_constraintEnd_toStartOf="@id/textButtonBarrierStart"
        app:layout_constraintStart_toEndOf="@id/imgAvatar"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Long Full Name is overlapping btnFollow" />

    <TextView
        android:id="@+id/btnFollow"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:layout_marginEnd="8dp"
        android:maxLines="1"
        android:text="Follow"
        android:textColor="?attr/textColorAzure"
        app:layout_constraintBaseline_toBaselineOf="@id/txtFullName"
        app:layout_constraintEnd_toStartOf="@id/btnPrimaryAction"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toEndOf="@id/txtFullName" />

    <TextView
        android:id="@+id/btnUnfollow"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:layout_marginEnd="8dp"
        android:maxLines="1"
        android:text="Unfollow"
        android:textColor="?attr/textColorGreyishBrown"
        android:visibility="gone"
        app:layout_constraintBaseline_toBaselineOf="@id/txtFullName"
        app:layout_constraintEnd_toStartOf="@id/btnPrimaryAction"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toEndOf="@id/txtFullName" />

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/textButtonBarrierStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="start"
        app:constraint_referenced_ids="btnFollow,btnUnfollow" />

    <TextView
        android:id="@+id/txtTitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="8dp"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="?attr/textColorGreyishBrown"
        app:layout_constraintEnd_toStartOf="@id/btnPrimaryAction"
        app:layout_constraintStart_toEndOf="@id/imgAvatar"
        app:layout_constraintTop_toBottomOf="@id/txtFullName"
        tools:text="Title" />

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/secondColumnEndBarrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="end"
        app:constraint_referenced_ids="btnFollow,btnUnfollow,txtTitle" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btnPrimaryAction"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toEndOf="@id/secondColumnEndBarrier"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Action" />

</androidx.constraintlayout.widget.ConstraintLayout>

How can I achieve this UI?


Solution

  • You need a couple of attributes:

    • In txtFullName to have match constraints width, so that its width can't exceed the barrier, and allow it to add the ellipsize just before the barrier.

      android:layout_width="0dp"
      
    • In btnFollow & btnUnfollow use layout_constraintWidth_min with wrap value so that they can make sure that they always take the preference of wrapping their contents even when the width matches the constraints with 0dp

      app:layout_constraintWidth_min="wrap"
      

    Preview now:

    enter image description here