I have a ConstraintLayout where its height is wrap_content.
I want its height to be able to collapse or expanding, according to its Child's height. Simple and common enough, right?
Now I have a layout which looks like this:
(First of all, please ignore the abnormal super large margin at the bottom. As you can see, the margin is just 16dp but the preview renders a very large margin.)
My problem is, if the big rectangle's visibility is set to gone,
According to the documentation of ConstraintLayout, if I set its goneMarginTop to a certainValue, it will retain that margin even when its visibility is gone. So that my Request Date will have some space to the bottom of parent.
However, this does not work as expected. Request Date sticked to the bottom of its parent:
(This is again a broken preview. In my real app, I am able to see a complete Request Date)
Have I done something wrong? Here is my complete code:
<?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="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="#color/colorBasicGrey"
android:layout_marginBottom="2dp">
<View
android:id="#+id/item_indicator"
android:layout_width="8dp"
android:layout_height="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="#color/white"
android:layout_marginTop="24dp"
android:layout_marginLeft="24dp"/>
<TextView
android:id="#+id/group_member_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/group_member_join_group_request"
app:layout_constraintTop_toBottomOf="#id/item_indicator"
app:layout_constraintBottom_toTopOf="#id/item_indicator"
app:layout_constraintLeft_toRightOf="#id/item_indicator"
android:layout_marginLeft="8dp"
style="#style/general45"/>
<TextView
android:id="#+id/group_member_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/general45"
android:textAllCaps="true"
app:layout_constraintBaseline_toBaselineOf="#id/group_member_label"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="180dp"
tools:text="ABCDEFGHIJK"/>
<TextView
android:id="#+id/group_request_date_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/group_member_request_date_label"
app:layout_constraintTop_toBottomOf="#id/group_member_label"
app:layout_constraintLeft_toLeftOf="#id/group_member_label"
android:layout_marginTop="8dp"
style="#style/general45"/>
<TextView
android:id="#+id/group_request_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/general45"
android:textAllCaps="true"
app:layout_constraintBaseline_toBaselineOf="#id/group_request_date_label"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="180dp"
tools:text="28/10/2017"/>
<LinearLayout
android:id="#+id/admin_button_container"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
android:layout_marginTop="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/group_request_date_label"
app:layout_constraintVertical_bias="0.0"
app:layout_goneMarginTop="16dp"
app:layout_goneMarginLeft="24dp"
app:layout_goneMarginRight="24dp"
app:layout_goneMarginBottom="0dp"
android:visibility="gone">
<!--To simplify the question, I hided elements inside this LinearLayout-->
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Figured it out.
goneMargin is used to indicate the margin to a GONE target, instead of itself being GONE.
Therefore in fact I should put the goneMargin attributes in the Request Date instead of the large rectangle.
Related
I have the following XML code , I couldn't make 'summaryViewPager' fill the remaining space vertically, until the bottom of the screen :
<?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">
<com.google.android.material.card.MaterialCardView
android:id="#+id/mainCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:background="#666266"
android:padding="10dp"
app:cardCornerRadius="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="2dp"
android:text="#string/category"
android:textColor="#FFBA93"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/cardView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:background="#666266"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/mainCardView">
<Button
android:id="#+id/shareButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:background="#drawable/ic_share"
app:layout_constraintEnd_toStartOf="#+id/copyButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/seenImageView"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="3dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:contentDescription="#string/todo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/favoriteButton"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/unseen" />
</com.google.android.material.card.MaterialCardView>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/summaryViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cardView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
The above code doesn't show the PageViewer at all below cardView2 , however when I set android:layout_height="500dp it does show PageViewer, but it doesn't fill the whole screen.
Initial Thoughts
I copy pasted your Layout into Android Studio 4.x, replaced all #string references with "something", and all #drawables with an existing one (from #android:drawable/) so my layout would render.
From what I see, it looks correct:
I noticed some inconsistencies in your Layout.
CardView Number 1 (top)
Careful with Padding on a CardView (don't know your min/max API so, not sure if this applies to you).
Your CardView has no constrain for its BOTTOM, it's left to "whatever size you compute after wrapping" (Height = wrap, Bottom_To = null).
This ^ means that for the CardView to have a height, all its innerwidgets must compute their sizes, so the top card view knows how much size + margin + padding it needs. It doesn't depend on OTHER widgets (that are not children) because its constrains are all to the parent. (rather it only needs its parent).
CardView Number 2 (bottom)
This cardView wraps all its dimensions but has the same issue as the one above, it doesn't constraint its height (except to be pinned at the bottom of the previous one, CardView 1). Again, this is fine, so as long as nobody depends on this (which is not true). This one has to wait on more widgets to know its size, because it has to wait on the CardView1 to know how much space is left, and also needs to know how much its children need. It's not too hard because both (the ImageView and the Button) have fixed sizes (20 and 30 dp respectively) + margins/padding.
The children of a MaterialCardView cannot/should not/must not use constraints because a CardView is not a ConstraintLayout, rather a glorified FrameLayout, which can only hold ONE child (or if it has more, it will put them on on top of the other). So all those constraints (for the shareButton and seenImageView) are ignored.
The solution to the above, is to have an inner ConstraintLayout as the sole child of a CardView, and inside this inner CL, put all your children and their constraints. The inner ConstraintLayout should have its width/height as either wrap_content or match_parent so they use the constraints of the parent. Since htey have fixed sizes, this is not an issue. (and if they didn't it wouldn't be an issue, but would need another measure pass).
Regardless of this, this second CardView is able to calculate its height, because its children are reporting a size of 20+30 (overlapped) + 15 margin top (image) so.. all this combined is likely 45dp~ of height (since they overlap only the biggest numbers apply here).
All the constraints are ignored for these two children.
ViewPager (bottom)
Finally we reach the VPager. This viewPager is match_parent for its width (since you have constraints to the start/end, you should just use 0dp). And it has wrap_content for its height.
layout_height=wrap_content -> this is a problem here. Because the viewPager doesn't (at the time of layout pass/measure) yet know what its contents are going to be. So you probably want this to be 0dp and let the ViewPager use all available space after the above has been calculated.
The marginTop you have here, will not work as it is, because the CardView 1 and 2 have no bottom constrain, so this one would have to create yet another layout/measure pass after it's all said and done to be able to apply a margin (that's how it works).
Ok Enough Rant - what can you do?
I'd "fix" the layout by adding the correct constraints and -if needed- use a VerticalChain and biasing for all widgets.
I'd fix the middle (Cardview 2) contents by wrapping the textview and imageView in a ConstraintLayout.
I'd remove left/right and replace with start/end (unless you target API 16 or below).
I'd set the ViewPager to 0dp on both dimensions.
The children of your CardView2 refer to copyButton and favoriteButton but these don't exist in the Layout you pasted, so I assume you have more buttons there).
Full Version (modified)
And in case you wonder, here's what I did ( I added a color to the VP's background so it was easier to "see").
<?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">
<com.google.android.material.card.MaterialCardView
android:id="#+id/mainCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
app:layout_constraintVertical_chainStyle="packed"
android:background="#666266"
android:padding="10dp"
app:cardCornerRadius="20dp"
app:layout_constraintBottom_toTopOf="#id/cardView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:layout_marginTop="2dp"
android:text="Category"
android:textColor="#FFBA93"
android:textSize="20sp"
android:textStyle="bold" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/cardView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:background="#666266"
android:padding="10dp"
app:layout_constraintBottom_toTopOf="#id/summaryViewPager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/mainCardView">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/innerCardView2Root"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/shareButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="5dp"
android:background="#android:drawable/ic_menu_share"
app:layout_constraintEnd_toStartOf="#+id/seenImageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/seenImageView"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="3dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="5dp"
android:contentDescription="#null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/shareButton"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/ic_menu_search" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/summaryViewPager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="2dp"
android:background="#color/colorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cardView2" />
</androidx.constraintlayout.widget.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!
I have an arbitrary length textview+icon (icon+text) that needs centering on the screen. On the same row, there is a button aligned to the right side of the screen. (X)
| icon+text | X |
Using a LinearLayout I can center it with the view, but the button on the right shifts it left.
With a relative layout, I can achieve what I want but if the text is too long the button overlaps the text.
What's the right way to do this? I haven't used constraintLayout before, would that solve it?
I suggest you to use a constraint layout,
Example:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".YourActivity">
<TextView
android:id="#+id/my_text_view"
android:text="My Long Text That must not overlap the button"
android:layout_width="0dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/my_btn"
app:layout_constraintTop_toTopOf="#+id/my_btn"
app:layout_constraintBottom_toBottomOf="#+id/my_btn"/>
<Button
android:id="#+id/my_btn"
android:layout_marginTop="16dp"
android:text="My Nice Button "
android:layout_marginEnd="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#id/my_text_view"
app:layout_constraintEnd_toEndOf="parent"/>
</android.support.constraint.ConstraintLayout>
Example Output:
You can set it like this,
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:drawableLeft="#mipmap/ic_launcher"
android:text="Click" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="TextView" />
</LinearLayout>
just use a Relative Layout.
Center your Textview
and put toRightOf=txtViewsName on the button.
//UPDATED Forcing Widths in DP to ensure text is always centered and never overlaps button.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#mipmap/ic_launcher"
android:maxWidth="230dp"
android:layout_centerHorizontal="true"
android:ellipsize="end"
android:text="My text to show test abcdefghyijkldkf here" />
<Button
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Button" />
</RelativeLayout>
You will need to adjust the button width and textview maxwidth to match your design, and confirm on preview all resolutions, but dp should cover you pretty well in this case.
NOTE*
This simply answers your issue, but does not do any funny behavior, i.e. if text grows too much ignore center command and start moving to the left, this does not do that. If that is your desire, please update your question.
//Centering Text in left view and using weight to ensure text area takes proper percentage of the space (based on your comments, not the layout you are looking for, but I'll leave it in case it helps someone else).
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="10">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="7"
android:drawableLeft="#mipmap/ic_launcher"
android:gravity="center"
android:text="My text to show here" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="Button" />
</LinearLayout>
for best practice i think ConstraintLayout is the best solution for designing and yes of course it helps you for what are you looking for.
for more info check this Build a Responsive UI with ConstraintLayout and this
ConstraintLayout.
Since your ImageButton on right has a fixed width (let's say 40dp for the purpose of this example) you can achieve the desired result by adding a margin of the same width at the end of your TextView to ensure that they're not overlapping. To keep the TextView centered on the screen you have to add the same margin at the start as well:
<android.support.constraint.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="wrap_content">
<TextView
android:id="#+id/textview"
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/button"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/textview"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
If you want to center the text within the TextView use android:gravity="center":
If the ImageButton's width was wrap_content then this approach wouldn't work, because there is no way to constraint the end of the TextView both to the end of the parent (so it's centered on the screen) and to the start of the ImageButton (so they don't overlap if the text gets long) at the same time.
In the end I ended up using RelativeLayout per Sam's suggestion with maxWidth and margin set on the TextView.
I can't figure out how to render my listItems correctly. Everything seems fine until the text title is too long. Looking at the pics below, I have the Title anchored on the left side of the listItem View and to the right of the imageView. I've even tried anchoring the right side to the right edge of the entire view but with no success. If the user enters a title too long the views overlap.
I want the title to be centered between the imageview and the left side of the entire listItem view. I have provided pics of how this all renders. Any help would be greatly appreciated. When the title gets long enough, it wraps the text which is fine. At this point I'd even settle for the trailing ... but I would prefer to have the text wrap. I just don't want to overlap the imageview. I have also posted the xml code
<?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:orientation="vertical"
android:padding="5dp"
android:id="#+id/list_item_container">
<TextView
android:id="#+id/match_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="16sp"
tools:text="Match Name"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="16dp"
app:layout_constraintRight_toLeftOf="#+id/imageView"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="#+id/match_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Match Date"
android:textAlignment="center"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toLeftOf="#+id/imageView"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/match_name"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"/>
<ImageView
android:id="#+id/imageView"
android:layout_width="60dp"
android:layout_height="45dp"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="8dp"
android:layout_weight="1"
app:srcCompat="#drawable/ic_more_vert_black_24dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
android:layout_marginRight="68dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintVertical_bias="0.484"/>
<TextView
android:id="#+id/match_id_hidden"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:visibility="invisible"
tools:layout_editor_absoluteY="67dp"
tools:layout_editor_absoluteX="24dp"/>
</android.support.constraint.ConstraintLayout>
Inside the ConstraintLayout try to always use "0dp" for your heights and widths and always set the app:layout_constraint..._to...Of for all 4 sides for all your views. Examine the outcome and then fine tune to get the expected result. Do this in the XML instead of in the visual editor; in my experience it is quicker and it avoids the layout_editor_absolute... settings.
Set android:layout_width="0dp" for both your TextViews. In a ConstraintLayout, a value of "0dp" basically means match the constraints. A value of "wrap_content" doesn't take constraints into account when measuring the views, just when positioning them.
I use :
compile 'com.android.support.constraint:constraint-layout:1.0.2'
The main problems are:
layout_margin can't be shown correctly;
child textview's text is clipped.
Details as below:
This is my xml:
<android.support.constraint.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="wrap_content"
android:background="#android:color/darker_gray"
android:padding="8dp">
<ImageView
android:id="#+id/reviewer_avatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="#color/colorAccent"
android:contentDescription="#string/avatar"
android:layout_margin="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/reviewer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/reviewer_name"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="#+id/comment_floor"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toTopOf="#+id/reviewer_avatar"
app:layout_constraintVertical_chainStyle="packed"/>
<TextView
android:id="#+id/comment_floor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/reviewer_floor_text"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="#+id/reviewer_avatar"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_name"/>
<TextView
android:id="#+id/comment_period"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="#string/comment_period_text"
android:textSize="12sp"
app:layout_constraintLeft_toRightOf="#+id/comment_floor"
app:layout_constraintTop_toBottomOf="#+id/reviewer_name"/>
<TextView
android:id="#+id/comment_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"/>
</android.support.constraint.ConstraintLayout>
This is my screenshot:
Here are mainly two problems
You missing to set right constraint for view with parent
There was an bug in ConstraintLayout with wrap_content which is resolved , now you have to use match_constraint(0dp) and layout_constraintWidth_default property to solve this issue
add below two properties to largetext view
android:layout_width="0dp"
app:layout_constraintWidth_default="wrap"
app:layout_constraintRight_toRightOf="parent"
So your largetext view would be like
<TextView
android:id="#+id/comment_content"
android:layout_width="0dp"
app:layout_constraintWidth_default="wrap"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"/>
I think I found the answer to child textview's text is clipped.
I change it:
<TextView
android:id="#+id/comment_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"/>
to
<TextView
android:id="#+id/comment_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"
app:layout_constraintRight_toRightOf="parent"/>
This would solve the problem !
But this way, TextView can't scalable,only fill width.
Finnaly, the better answer:
<TextView
android:id="#+id/comment_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/reviewer_name"
android:textSize="16sp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintLeft_toLeftOf="#+id/reviewer_name"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"
app:layout_constraintWidth_default="wrap"/>
layout_margin can't be shown correctly; - margins space is outside view's bounds. app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar" means that reviewer_name is constrained to the right side of reviewer_avatar not including margins. Set android:layout_marginLeft="8dp" of reviewer_name, comment_floor and comment_content.
child textview's text is clipped. - width of the comment_content is equal to the width of your ConstraintLayout, but the comment_content is constrained to the right side of reviewer_avatar. Therefore the right side of the comment_content goes beyond the boundaries of the ConstraintLayout, i.e. is clipped. Set the specific width of the comment_content for different screen sizes.
I believe this is a resize bug that should be fixed in 1.1 beta 1 (see https://androidstudio.googleblog.com/2017/05/constraintlayout-110-beta-1-release.html to install it) -- please try it and see if that's it.