Search code examples
androidandroid-layoutandroid-constraintlayout

Android keep TextView's drawableLeft aligned to centered dynamic text


I have a problem with the selected TextView in the image below, I use ConstraintLayout.

Layout

After placing some string resource files for a number of languages I encountered the case where the TextView overlapped the other Views because the new strings were too long and I was using a width of wrap_content. So I changed from wrap_content to match_constraint and the TextView was wrapping on multiple lines, which is good, but now the drawable attached to the left of the TextView is too far from the text in cases where the string is short. That is because I am using gravity center and it leaves a big whitespace gap between the text and drawable.

It seems I can't find a solution without affecting the multiple line strings. Hardcoding for every corner case language can be done and shouldn't be a problem now, but as I scale to more languages it is not the ideal solution.

Tried to solve it through code instead on xml and just put a condition if lineCount of the TextView was 1, then I needed to use wrap_content instead of match_parent because it is not overlapping, but I doesn't seem to work consistently, because the view drawing is not finished and it has problems on screen rotations.

This is what I want:

Expected

This is what I get:

Actual

And here is the xml that I have, if it is helpful, I don't mind breaking it into multiple components, but until now a single TextView with a drawableLeft was enough. Thank you.

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/header_root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/blue"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <TextView
        android:id="@+id/back_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:drawablePadding="10dp"
        android:textColor="#D3DDDD"
        android:textSize="14sp"
        android:visibility="invisible"
        app:drawableStartCompat="@drawable/left_arrow"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/refresh_text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:drawablePadding="8dp"
        android:gravity="center"
        android:text="@string/pull_down_to_refresh"
        android:textColor="@color/white"
        android:textSize="14sp"
        app:drawableStartCompat="@drawable/refresh"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/legend"
        app:layout_constraintStart_toEndOf="@+id/back_text"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/rotation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="20dp"
        android:src="@drawable/rotate_device"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/legend"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginEnd="10dp"
        android:layout_toStartOf="@+id/rotation"
        android:src="@drawable/legend_inactive"
        app:layout_constraintBottom_toBottomOf="@+id/rotation"
        app:layout_constraintDimensionRatio="1"
        app:layout_constraintEnd_toStartOf="@+id/rotation"
        app:layout_constraintTop_toTopOf="@+id/rotation" />
</androidx.constraintlayout.widget.ConstraintLayout>

Solution

  • For your use-case you can use MaterialButton because it provides icon & very important in your case iconGravity=textStart.

    So your layout would like look like this:

    <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/header_root"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/blue"
            android:paddingTop="10dp"
            android:paddingBottom="10dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <TextView
                android:id="@+id/back_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:drawablePadding="10dp"
                android:textColor="#D3DDDD"
                android:textSize="14sp"
                android:visibility="invisible"
                app:drawableStartCompat="@drawable/left_arrow"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
            <com.google.android.material.button.MaterialButton
                android:id="@+id/refresh_text_view"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginEnd="8dp"
                android:drawablePadding="8dp"
                android:gravity="center"
                android:text="Pull to refreshmckdmcdkmckdsmckdsmckdcm"
                android:textColor="@color/white"
                android:textSize="14sp"
                android:background="@android:color/transparent"
                app:icon="@drawable/refresh"
                app:iconGravity="textStart"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/legend"
                app:layout_constraintStart_toEndOf="@+id/back_text"
                app:layout_constraintTop_toTopOf="parent" />
    
            <ImageView
                android:id="@+id/rotation"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="20dp"
                android:src="@drawable/rotate_device"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
            <ImageView
                android:id="@+id/legend"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_marginEnd="10dp"
                android:layout_toStartOf="@+id/rotation"
                android:src="@drawable/legend_inactive"
                app:layout_constraintBottom_toBottomOf="@+id/rotation"
                app:layout_constraintDimensionRatio="1"
                app:layout_constraintEnd_toStartOf="@+id/rotation"
                app:layout_constraintTop_toTopOf="@+id/rotation" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    

    Output with long text:

    long text

    Output with short text:

    short text