I'm using a RecyclerView to show a list of country codes, countries and flags respecively. The app is supporting RTL, so the layout of item is a simple Constraintlayout with 3 elements:
<?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"
android:background="#drawable/selectable_background">
<ImageView
android:id="#+id/countryFlag"
android:layout_width="24dp"
android:layout_height="24dp"
android:scaleType="centerInside"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/countryName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/countryCode"
app:layout_constraintStart_toEndOf="#+id/countryFlag"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/countryCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
But sometimes I get this visual representation in RTL (Arabic) like this, where some items are not aligned properly. See Angola and Anguilla country items:
You need a fixed width for the country code, this is what is misaligning the text
There is no reason for countryName to fill the entire width, the constraint layout's width is already match_parent and countryName's start already aligned to the flag's end.
Align using constraints is much more stable then android:textAlignment attribute.
Edit it as follows
<TextView
android:id="#+id/countryName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/countryCode"
app:layout_constraintStart_toEndOf="#+id/countryFlag"
app:layout_constraintTop_toTopOf="parent" />
Happy to help
Related
basically I have an layout as shown in the image. I am using a Guideline to restrict the width of the blue box. This means the ConstraintLayout itself hase full screen width and the blue box has its layout_constraintEnd_toStartOf="#id/guideline".
The blue box is just the background color of the TextView with the text, there aren't any additional containers or anything.
In order for the blue box to respect the constraints for its width calculations I have to set layout_constrainedWidth="true" on the box. As you can see the width is then restricted but the problem is that wrap_content does not work correctly afterwards.
The first box shows that if the text is only a single line, then the behaviour is as expected but if the text spans multiple lines (as in the second box) wrap_content breaks and the box is always "full width" (start of screen until the guideline).
Did somebody experience something similar? Is this a bug or did I misunderstood something. The same broken behaviour can be observed with the grey box on the right side.
I assume this has to do with the breaking behaviour of the TextView but is there a fix or workaround? As far as I know outside of an ConstraintLayout the width would be equal to the text so I assume this is a bug.
Edit XML code:
This is the basice code of one of the "bubbles" and as already mentioned I would like the view to really be as wide as the text.
<?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">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/chat_message_history_receiver_background"
android:fontFamily="#font/nunito_semibold"
android:includeFontPadding="false"
android:paddingStart="15dp"
android:paddingTop="10dp"
android:paddingEnd="15dp"
android:paddingBottom="10dp"
android:textColor="#FFFFFF"
android:textSize="17sp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/guideline"
app:layout_constraintStart_toEndOf="#id/profile_image"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
app:layout_constraintWidth_max="wrap"
tools:text="Just testing something, somehowthisisnotworking" />
<app.jooy.messenger.ui.components.generic.profile_image.ProfileImage
android:id="#+id/profile_image"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginEnd="10dp"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintVertical_bias="1"
app:backgroundColor="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.85" />
</androidx.constraintlayout.widget.ConstraintLayout>
And here is the output of this particular xml code:
Try with this, adjust margin and padding as per your need. and change the android:layout_marginBottom of the guide as per your need.
<?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:paddingStart="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorPrimaryDark"
android:includeFontPadding="false"
android:paddingStart="15dp"
android:paddingTop="10dp"
android:paddingEnd="15dp"
android:paddingBottom="10dp"
android:textColor="#FFFFFF"
android:textSize="17sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guide"
app:layout_constraintWidth_percent=".8"
tools:text="Just testing something, Some how this is not working" />
<app.jooy.messenger.ui.components.generic.profile_image.ProfileImage
android:id="#+id/profile_image"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginStart="5dp"
app:backgroundColor="#color/colorPrimary"
app:layout_constraintStart_toStartOf="#id/text"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/guide"
android:layout_width="0dp"
android:layout_height="0.2dp"
android:layout_marginBottom="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="#id/profile_image"
app:layout_constraintVertical_bias="1"
app:layout_constraintTop_toTopOf="#id/profile_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
I'm using ConstraintLayout to display a RecyclerView or a Image with TextView conditionally based on the data in the RecyclerView. The problem is that the Image and TextView won't center vertically even when I've properly put constraints on all 4 directions. I'm also using the packed chain style. Here's my layout:
<?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:gravity="center"
app:layout_constraintVertical_chainStyle="packed"
tools:context=".ShortlistFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/shortlistedProfilesRV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="#+id/interestProgress"
style="#style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:mpb_progressStyle="horizontal" />
<ImageView
android:id="#+id/shortlistBgImageView"
android:layout_width="128dp"
android:layout_height="121dp"
android:contentDescription="Star image"
android:src="#drawable/star"
app:layout_constraintBottom_toTopOf="#id/shortlistHelperText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/shortlistHelperText"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Some Text Here!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/shortlistBgImageView"
app:layout_constraintVertical_chainStyle="packed" />
</androidx.constraintlayout.widget.ConstraintLayout>
In Android Studio Preview the image and text is totally centered as expected. But in an actual device its at the top (I'm texting Android 9). I need to give layout_marginTop to my ImageView to have it centered, but that is just a hacky way of doing things. What am I doing wrong here?
I was actually using this fragment inside a NavHostFragment which had its height set to wrap_content.
I wonder how to implement the following design in Android xml. The contents will have height wrap-contents with the most priority, and it could even fill the whole screen if there are enough contents. The image above it should fill up the remaining height - however it also has a limited max-height of 160dp. It seems if I use layout-weight or match-parent, the max-height param does not work anymore. Is there a way to do this in the xml? Or do I have to do it in the Java file programmatically? Thanks.
try something like this:
I'm using two textView just for test
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#42A5F5">
<TextView
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#EC407A"
android:maxHeight="160dp"
android:text="Image"
android:textSize="48sp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#FFEE58"
android:text="Content"
android:textSize="48sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
those are the important lines
android:maxHeight="160dp"
app:layout_constrainedHeight="true"
I am attempting to design a chat item in a RecyclerView with constraint layout but a can't set the flexible width correctly.
Android constraint layout:
<?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:id="#+id/receive_message_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/receive_message_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="textStart"
android:textColor="#color/receive_message_box_text"
android:background="#drawable/message_recieve"
android:padding="#dimen/message_box_padding"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/receive_time_label"
app:layout_constraintHorizontal_chainStyle="spread_inside"
/>
<TextView
android:id="#+id/receive_time_label"
android:layout_width="wrap_content"
app:layout_constrainedWidth="true"
android:layout_height="wrap_content"
android:text="timestamp"
android:textAlignment="textEnd"
android:layout_marginStart="#dimen/space_between_message_element"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#id/receive_message_label"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="HardcodedText"
/>
</android.support.constraint.ConstraintLayout>
It works well but if I show some longer message, the timestamp is hidden by receive message label.
The solution from anber is good, but the chat content textView will have extended width, even when the content is very short, which may become not good.
I also did something very similar. Finally I used a solution as:
use a LinearLayout (or any other layout) which has width=0 (match_constraint) to replace the TextView
move TextView as child of above layout, and set its width=wrap_content
Thus the time will show anyway, and the chat content width is still wrapped.
UPD. My previous solution was incorrect as #aimin-pan mentioned.
you should set for you message textView
android:layout_width="wrap_content" and app:layout_constrainedWidth="true", and right constraint before left side of time textView.
And time textView just align on top-right of parent.
In this case if you have short text it will be wrap context:
And if the text is long it will also correct wrap:
Full 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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="#F00"
android:text="asdf asdf aasdf"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="#+id/button"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
In your time TextView remove this line
app:layout_constraintStart_toEndOf="#id/receive_message_label"
So, the time label is not constrained to the message, but only the message to the time.
Set also the message label width to 0dp
android:layout_width="0dp"
Place a Blank View After Time textView
<View
android:id="#+id/view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="#+id/constraintLayout3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/constraintLayout3"
app:layout_constraintTop_toTopOf="#+id/constraintLayout3" />
I have an XML file with an ImageView and a TextView. Everytime that the TextView is populated, the text goes off of the screen. I looked at other people who have had the same problem and the common solution seems to be to set the Textview's width to 0dp. This hasn't worked for me. Wondering if anyone knows why?
Here is my constraintLayout XML file:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="#+id/weather_icon"
app:layout_constraintRight_toLeftOf="#id/weather_data"
android:layout_width="50dp"
android:layout_height="match_parent" />
<TextView
android:id="#+id/weather_data"
android:text="EXAMPLE"
android:textStyle="bold"
android:paddingRight="16dp"
style="#style/TextAppearance.AppCompat.Large"
app:layout_constraintLeft_toRightOf="#id/weather_icon"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Here is what it looks like, text is clearly getting cut off:
I got the solution of your problem just use it:
<?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="match_parent">
<ImageView
android:id="#+id/weather_icon"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/weather_data"
android:layout_width="50dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/weather_data"
android:text="EXAMPLE "
android:textStyle="bold"
android:paddingRight="16dp"
style="#style/TextAppearance.AppCompat.Large"
app:layout_constraintLeft_toRightOf="#id/weather_icon"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>
You should set the width of your TextView to match_constraint which, in the XML, will be 0dp.
And I see you're using both left/right and start/end notations. Stick to only one of them.
I encourage you to use the start/end notation because there might be devices using your app that their language is one that reads from right to left, i.e.: Arabic, so using the start/end you don't have to worry about these devices.
Thanks to Sandeep and Martin. I combined their suggestions and this works well in the layout:
<ImageView
android:id="#+id/weather_icon"
app:layout_constraintEnd_toStartOf="#id/weather_data"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="50dp"
android:layout_height="wrapcontent" />
<TextView
android:id="#+id/weather_data"
android:text="EXAMPLE"
android:textStyle="bold"
android:paddingRight="16dp"
app:layout_constraintStart_toEndOf="#id/weather_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
style="#style/TextAppearance.AppCompat.Large"
android:layout_width="0dp"
android:layout_height="wrap_content" />