Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Constraints instead of the maxWidth attribute for width limits

I was wondering if it's possible to achieve the following (message thread; starting first with the sender's, right side as opposed to the recipient's side) view:

enter image description here

... using Android's Constraints from the support library instead of the maxWidth attribute, particularly for the width of the text bubbles - I pretty much want a container's width (consisting of a TextView along with its rounded background, and the sender's ImageView icon) width to be four-fifths of the screen at most, and then wrap the following lines of text below accordingly just like standard messaging apps. Because as of now, I wasn't able to achieve it using constraints' guidelines as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">

    <android.support.constraint.Guideline
        android:id="@+id/left_margin_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.2"/>

    <android.support.constraint.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="@dimen/padding_one_half"
        app:layout_constraintStart_toEndOf="@+id/left_margin_guideline"
        app:layout_constraintEnd_toEndOf="parent">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/message_icon"
            android:layout_width="@dimen/conversation_icon_size"
            android:layout_height="@dimen/conversation_icon_size"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            tools:src="@drawable/ic_toolbar_logo"/>

        <io.github.rockerhieu.emojicon.EmojiconTextView
            android:id="@+id/message_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/ic_curved_corners_message"
            android:padding="@dimen/padding_one_half"
            android:layout_marginRight="@dimen/padding_one_half"
            android:layout_marginEnd="@dimen/padding_one_half"
            app:layout_constraintEnd_toStartOf="@+id/message_icon"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            tools:text="This is a message that should wrap if it gets too long or if there is a \nnewline in the middle of the message"/>

        <TextView
            android:id="@+id/message_posted"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/font_small"
            android:textColor="@color/colorGrayXLight"
            android:layout_marginTop="@dimen/padding_one_half"
            app:layout_constraintTop_toBottomOf="@+id/message_text"
            app:layout_constraintEnd_toEndOf="@+id/message_text"
            tools:text="2:45 PM"/>

    </android.support.constraint.ConstraintLayout>

</android.support.constraint.ConstraintLayout>

... which resulted in:

enter image description here

As you'll notice, the message text gets cut off from the beginning, and if I were to set the text's start constraint with the parent, then it defeats the whole purpose for one-lined texts (i.e. single word) since the text's width would then match the parent with the text being centered when I want it to be wrapped just like how it is in the screenshot above at the top.

All of that said, it'd be nice if I could make this work out with constraints since I want this layout to be as responsive as possible on other screen sizes without using the maxWidth attribute either with a hardcoded value or setting it programmatically based on the screen size which I find terribly inconvenient in terms of boilerplate code, especially for a message thread view.

like image 314
DaveNOTDavid Avatar asked Mar 24 '18 16:03

DaveNOTDavid


1 Answers

Yes, you can achieve that using a biased centered constraint (left + right + bias 1) and constrainedWidth on that text element (with ConstraintLayout 1.1):

enter image description here

  <?xml version="1.0" encoding="utf-8"?>
  <android.support.constraint.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">

    <TextView
        android:id="@+id/textView7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="32dp"
        android:text="a message that should wrap if it is too long or if there is a space in the middle of the text"
        app:layout_constrainedWidth="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/imageView2"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher_round" />

    <TextView
        android:id="@+id/textView8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="2:45 PM"
        app:layout_constraintEnd_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/textView7" />
</android.support.constraint.ConstraintLayout>

Replacing the text with a shorter message it adapts correctly:

enter image description here

like image 117
Nicolas Roard Avatar answered Sep 28 '22 19:09

Nicolas Roard