san_francisco
san_francisco

Reputation: 53

TextView goes beyound the ConstraintLayout

I would like to get a effect dotted text(ellipsis property) - both textView in this same line, but I have problem with ConstraintLayout.

In first TextView if I have long text, my second textView going to off screen. I would like to block second textView on the end of layout and dotted 1st textView.
It is possible ?

Screens:

short text

long text

xml:

    <?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="match_parent"
    android:background="@color/colorPrimary"
    android:padding="16dp"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="36dp"
        android:background="#00D54C4C"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="longTextlongTextlongTextlongTextlongTextlong"
            app:layout_constraintStart_toStartOf="parent"
            tools:layout_editor_absoluteY="85dp" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="123456789"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toEndOf="@+id/textView2"
            tools:layout_editor_absoluteY="85dp" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Upvotes: 0

Views: 298

Answers (2)

CodyEngel
CodyEngel

Reputation: 1501

Your constraints aren't correct as you don't have an end constraint. The following should resolve that issue:

<?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="match_parent"
    android:background="@color/colorPrimary"
    android:padding="16dp"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="36dp"
        android:background="#00D54C4C"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="longTextlongTextlongTextlongTextlongTextlong"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            tools:layout_editor_absoluteY="85dp" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="123456789"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            tools:layout_editor_absoluteY="85dp" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

That however still leaves you with some fairly gnarly layout code that isn't too great. There is never a good reason to have nested ConstraintLayouts so I'd recommend refactoring it to be something like this (which will still give you same end result):

<?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="match_parent"
    android:background="@color/colorPrimary"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="longTextlongTextlongTextlongTextlongTextlong"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="123456789"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView2"/>

</androidx.constraintlayout.widget.ConstraintLayout>

The above also includes vertical constraints (constraintTop_...) which will ensure the layout displays correctly at runtime and will also resolve the IDE warning you had with the code previously.

And then from there to get the ellipsize effect you just need to add the following attributes to your TextView: android:ellipsize="end" and android:lines="1"

The final XML would look something like this:

<?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="match_parent"
    android:background="@color/colorPrimary"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="longTextlongTextlongTextlongTextlongTextlonglongTextlongTextlongTextlongTextlongTextlong"
        android:ellipsize="end"
        android:lines="1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="123456789"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView2"/>

</androidx.constraintlayout.widget.ConstraintLayout>

One thing to note: this does remove the margin you had previously. Making use of Guideline you are able to add the margins/padding you wanted by adding a start and end Guideline which has a vertical orientation. The final-final version of the layout would look something like this:

<?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="match_parent"
    android:background="@color/colorPrimary"
    android:padding="16dp"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineStart"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="16dp" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineEnd"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_end="16dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="longTextlongTextlongTextlongTextlongTextlonglongTextlongTextlongTextlongTextlongTextlong"
        android:ellipsize="end"
        android:lines="1"
        app:layout_constraintStart_toStartOf="@+id/guidelineStart"
        app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="123456789"
        app:layout_constraintStart_toStartOf="@+id/guidelineStart"
        app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
        app:layout_constraintTop_toBottomOf="@id/textView2"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Having TextViews On Same Line

If you want to have the TextViews on the same line you can use another Guideline to include where the first should stop and the second should begin. In this example the guideline is set at the halfway point using app:layout_constraintGuide_percent=".5":

<?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="match_parent"
    android:background="@color/colorPrimary"
    android:padding="16dp"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineStart"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="16dp" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineCenter"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".5" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineEnd"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_end="16dp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="longTextlongTextlong"
        android:ellipsize="end"
        android:lines="1"
        app:layout_constraintStart_toStartOf="@+id/guidelineStart"
        app:layout_constraintEnd_toStartOf="@+id/guidelineCenter"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="123456789"
        app:layout_constraintStart_toStartOf="@+id/guidelineCenter"
        app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Upvotes: 2

zedlabs
zedlabs

Reputation: 523

Add the following to your text view you want to ellipsize(...)

android:ellipsize="end"
android:singleLine="true"

Upvotes: 0

Related Questions