TextView can't wrap arround text in ConstraintLayout - android

I've got an issue with TextView in ConstraintLayout, the xml with constraints looks like this:
<TextView
...
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/section_title"
tools:text="Data Processing, Hosting, and Related Services"
/>
The whole TextView is styled and in style I'm using flag android:breakStrategy="balanced" so the TextView presents like this:
As you can see it's expanding it's width to fill the constraint and doesn't wrap around the text so the background doesn't display correctly. Anyone knows the solution?

Remove this tag app:layout_constraintEnd_toEndOf="parent"
Reason -
you have given constraint to textview which will align itself to end
of parent, so app:layout_constraintStart_toStartOf="parent" is enough
to align it to start of parent and it will wrap content as a
background
Example
<TextView
...
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/section_title"
tools:text="Data Processing, Hosting,\nand Related Services"
/>

Related

Clickable Text + Image using TextView in Android

How to put an clickable image in between string using a single TextView.
Using SpannableString, I am able to color part of string. But how to add a colored image? Any suggestion would be really appreciated.
This is not possible for a single TextView element. TextViews are not meant to contain images in the middle of them.
You can, however, add drawable resources to the top, right/start, left/end, or bottom of a given TextView by leveraging the drawableTop, drawableBottom, etc. attributes. But again, no way of adding an image in the middle of a TextView by using only one of them.
If you really want that specific effect, I would group a few XML components into any ViewGroup like a ConstraintLayout to get exactly what you want; e.g.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_part_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="first part of the text"
android:textSize="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/image"/>
<ImageView
android:id="#+id/image"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/white"
app:layout_constraintStart_toStartOf="#id/text_part_1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="#id/text_part_2"/>
<TextView
android:id="#+id/text_part_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="first part of the text"
android:textSize="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#id/image"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Constraint Layout Centre Text Position with End Reference to Other Widget

I have a dialog widget with navigation bar contains title and close button. I want to put the title in centre of the device, and put the close button in the end of layout. However when the title is long, then it will overlap with the close button. Here is my code:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:maxLines="1"
android:ellipsize="end"
android:text="Title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="Close" />
</androidx.constraintlayout.widget.ConstraintLayout>
Any workaround to achieve this?
Thank you.
Normally, to center text, you would constrain the start and end of the text to the end point of the centering region. In this case, since the text should be centered on the screen, you would attach the start to the parent start and the end to the parent end. This works unless the centered text exceeds the empty center region and overlaps the "Close" TextView. Unfortunately, there is no way to make these constraints and tell the centered view to avoid overlapping the TextView on the right.
To make it work, I would introduce another TextView that is a duplicate of the "Close" TextView, make it invisible and attached to the top and start of the parent. This will create a region between the two TextViews where the text can be centered. To ensure that the text does not overlap the end TextView, specify app:layout_constrainedWidth="true" on the centered view. Something like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close"
android:visibility="invisible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="This is some very long text that should stretch across the device and ellipsize."
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="#+id/textView2"
app:layout_constraintStart_toEndOf="#+id/space"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="left"
tools:layout_editor_absoluteX="306dp"
tools:layout_editor_absoluteY="62dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
which will show in the designer like this for long text:
and like the following for short text:
There are other ways to do this that would involve some coding, but this is an XML-only solution which, IMO, is preferable.

Allow TextView to grow until a certain point in constraint layout

There is TextView1 and TextView2. TextView2 should float on the right side of TextView1. TextView1 should grow to the right as long as the total width of both text views do not make TextView2 overlap with the box on the right. When this happens, TextView1 should wrap to a second line.
When there is only one TextView, this is achievable by setting TextView's width to 0dp and constraining the size to the box. But with two text views I don't know how to achieve this.
You can achieve this with the use of the following attributes:
app:layout_constraintHorizontal_bias="0": makes sure the first text view leaves no space on the left.
app:layout_constraintHorizontal_chainStyle="packed": removes spacing between items in the text view chain.
app:layout_constrainedWidth="true": allows the use of wrap_content on the text view while still allowing to wrap if text is too long.
Here's the layout:
<TextView
android:id="#+id/text_view_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="#id/text_view_2"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Very long text in this text"
app:layout_constraintHorizontal_bias="0"
/>
<TextView
android:id="#+id/text_view_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintEnd_toStartOf="#id/box"
app:layout_constraintStart_toEndOf="#id/text_view_1"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text"
/>
<View
android:id="#+id/box"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
I suggest you try removing each attribute to see what effect they have.

TextView going out of screen with constraintLayout

I am using ConstraintLayout to create below xml in my application.
As you can see my first item is fine, But in the second one, some parts of my textView are not on the screen!
This is my XML code:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/ly_user"
android:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
app:layout_constraintRight_toRightOf="parent"
android:id="#+id/im_user_icon"
android:layout_width="#dimen/default_message_icon_size"
android:layout_height="#dimen/default_message_icon_size"
android:src="#drawable/user_pacific"/>
<ImageView
app:layout_constraintTop_toBottomOf="#+id/im_user_icon"
app:layout_constraintRight_toLeftOf="#+id/im_user_icon"
android:id="#+id/im_user_arrow"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/arrow_bg1"/>
<View
android:id="#+id/view_user_guidLine"
android:layout_width="1dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="#id/im_user_arrow"
app:layout_constraintRight_toRightOf="#id/im_user_arrow"/>
<TextView
app:layout_constraintTop_toBottomOf="#+id/im_user_icon"
app:layout_constraintRight_toLeftOf="#+id/view_user_guidLine"
android:id="#+id/tv_user_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="right"
android:padding="8dp"
android:minWidth="#dimen/default_message_textarea_width"
android:minHeight="#dimen/default_message_textarea_height"
android:background="#drawable/bg_right_text"
android:textColor="#android:color/white"/>
</android.support.constraint.ConstraintLayout>
I Know I can fix this problem to adding below line to the textView, But I need my textView be wrapContent.
app:layout_constraintLeft_toLeftOf="parent"
You can set your TextView's width to wrap_content, but to prevent it from expanding outside of screen you need to add the left constraint as well and use app:layout_constrainedWidth="true" to enforce constraints.
Now, to make the TextView stick to the right, you need to add app:layout_constraintHorizontal_bias="1", which will align it to its right constraint.
So all in all, these are the changes needed for the TextView:
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="1"
android:layout_width="wrap_content"
Add these following line in your code in your TextView
app:layout_constraintWidth_percent="0.6"
first line layout_constraintWidth_percent is 60 percent of your phone screen width you can change it according to your need.
Accepted answered works but on my side I use android:layout_width="0dp" because my TextView is in the middle of two elements.
<TextView
android:id="#+id/my_id_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/long_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/second_vertical_divider_view"
app:layout_constraintStart_toEndOf="#+id/first_vertical_divider_view"
app:layout_constraintTop_toTopOf="parent" />
Accepted answer didn't helped in my case. Alternative solution can look like that:
<ConstraintLayout>
<TextView
android:id="#+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
app:layout_constraintEnd_toStartOf="#+id/option_info"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_max="wrap" />
<ImageView
android:id="#+id/option_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_info"
app:layout_constraintBottom_toBottomOf="#+id/title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/title"
app:layout_constraintTop_toTopOf="#+id/title" />
</ConstraintLayout>
The idea is to prevent one view pushing another while expanding by creating a chain and add some constraint params to hold influenced view in view's border.
Hope it still will help somebody!

How can I prevent a TextView in a ConstraintLayout Chain from pushing other TextViews beyond their constraints while using layout_constrainedWidth?

My end goal is to have two single-line TextViews in a left-aligned, packed horizontal chain that allows both of them to grow to fill the remaining space, splitting it evenly if necessary, ellipsizing when there's not space.
Visual Aid:
And here's the layout code that I've tried to accomplish this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
tools:text="#tools:sample/lorem"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/textView2"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:ellipsize="end"
android:maxLines="1"
tools:text="#tools:sample/lorem"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="#id/textView1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
As you can see, I've laid out two textviews in a horizontal chain. I've got the chain style set to packed so that they stay together. I've got the horizontal bias set to 0 so that the chain is left aligned. I've got the width set to wrap_content so that they don't stretch when the text is short, and I've also set app:layout_constrainedWidth="true" so that they don't go past their bounds when the text is long. This works almost exactly how I want except when the text in textView2 grows. As textView1 grows, it pushes textView2 to the right until it hits its constraint, at which point it ellipsizes (as expected/desired), but the same is not true for textview2. As textView2 grows, it stretches to fill the room to its right, but once it hits its constraint, instead of ellipsizing, it keeps stretching and starts to push textView1 to the left until it is no longer visible at all.
Visual aid (actual behavior):
I've tried to use things like setting layout_constraintHorizontal_weight to .5 on each view but that has no effect unless I change both view widths to 0dp (match_constraints) which breaks the scenario where both views have short text (it adds extra space between the two text views).
What it feels like is that when you combine width=wrap_content with layout_constrainedWidth=true, the weight values are ignored. Is this just a limitation of ConstraintLayout? I've spent a lot of time trying to figure out a way to make this work and right now it doesn't seem like it's possible. I've fallen back to using a LinearLayout and making some design compromises, but I'd really like to get this working if anyone has any ideas. Thanks!
If someone is still looking for an answer, I think the following code will help.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/text1"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintWidth_max="wrap"
app:layout_constraintWidth_percent="0.5"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/text2"
app:layout_constraintHorizontal_chainStyle="packed"
android:background="#ff0000"
android:text="This is what you are looking for ?"
/>
<TextView
android:id="#+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintWidth_max="wrap"
app:layout_constraintWidth_percent="1"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/text1"
app:layout_constraintEnd_toEndOf="parent"
android:background="#ee0"
android:text="This is a Long Text TextView2 And not something else"
/>
</android.support.constraint.ConstraintLayout>
I needed a fix in the another answers.
And performs the following actions.
<TextView
android:id="#+id/first_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintHorizontal_bias="0" <!-- if you want gravity left -->
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/second_tv"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
tools:text="ABCDEFGHIJKLMNOPQRSTU" />
<TextView
android:id="#+id/second_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/first_tv"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
tools:text="VWXYZ" />
In ConstraninLayout if you want set weight such as linearLayout's weight , you should set value between 0..1 in (layout_constraintWidth_percent):
app:layout_constraintWidth_percent="1"
or
app:layout_constraintWidth_percent="0.5"
and also  connect the beginning and the end of component to each other:
app:layout_constraintStart_toEndOf="#id/textView1"
app:layout_constraintEnd_toStartOf="#id/textView2"
completed code:
<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">
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/textView2"
app:layout_constraintWidth_percent="0.5"
android:background="#color/yellow_light"
android:text="This is a long text that showing in textview1.This textview is a expanded textview.if you don't set (android:maxLines='1'),the whole text will be show." />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/textView1"
app:layout_constraintWidth_percent="1"
android:background="#color/orange_dark"
android:maxLines="1"
android:text="This is a long text that showing in textview2 that set (android:maxLines='1')" />
</androidx.constraintlayout.widget.ConstraintLayout>

Categories

Resources