Why is 0dp the same as wrap_content in this ConstraintLayout? - android

New to XML and was trying practising an XML lab (https://github.com/harshitha-akkaraju/layoutlab)
What confuses me is that even though the width of the button is 0dp, it is if the width was wrap_content. I know that 0dp is the equivalent of "MATCH_CONSTRAINT" in a ConstraintLayout. However, doesn't that mean that 0dp should fill as much space as possible?
Is it because the button only has a constraint defined on its left side, which is why 0dp = wrap_content in this case?
0dp, which is the equivalent of "MATCH_CONSTRAINT
<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="match_parent">
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp"
android:text="1"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Image of the Button Layout

In order for the button to match the parent layout, you need to set two opposite constraints....as in
<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="match_parent">
<Button
android:id="#+id/button1"
<!-- Since you are setting width as 0dp, i presume you want the width to match... -->
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp"
android:text="1"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
<!-- You must add here another constraint to the right -->
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>```

You are missing this line app:layout_constraintRight_toRightOf="parent"
in your button 0dp works with parent when
app:layout_constraintLeft_toLeftOf="parent" and app:layout_constraintRight_toRightOf="parent"
then width should be 0dpand when
app:layout_constraintBottom_toBottomOf="parent" and app:layout_constraintTop_toTopOf="parent"
then height should be 0dp

Related

Android XML ScrollView wrap_content height inside ConstraintLayout

I have the following 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/header"
style="#style/CustomFont_Header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
android:text="#string/welcome_header"
android:textAlignment="center"
android:textColor="#color/text_header"
tools:text="Header Title"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.1" />
<ScrollView
android:id="#+id/scrollview"
android:layout_width="#dimen/subtext_width"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/subtext_margin_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/header">
<TextView
android:id="#+id/subtext"
style="#style/CustomFont_Subheader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:text="#string/welcome_text"
android:textColor="#color/color_subtext"
tools:text="#string/testtext_short" />
</ScrollView>
<ImageView
android:id="#+id/logo"
android:layout_width="300dp"
android:layout_height="150dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:scaleType="fitCenter"
android:src="#drawable/logo_pic"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/scrollview"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I want to make subtext scrollable, because it can sometimes be short sometimes long.
I can make it work if I change scrollView and add:
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/logo
But in this case, if the text is short, then the logo is pushed to the bottom:
I always need to have the logo in the middle between the subtext and parent bottom and at the same time subtext must be constraint to the bottom of header if it is short.
I can think of something programmatically, but I think it can be done in XML, right?
Do not give the wrap content width. Make it match parent and provide the padding to first layout in the scroll bar
Remove these two lines from ScrollView:
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/logo
And add
android:fillViewport="true"
And do not give the ScrollView height as 'wrap_content' set the height of the ScrollView to some fixed dp e.g 120dp then you will be able to have the scrollable text between header and logo.

Why is the text in the text view cut off in the recycler view?

I'm trying to make an items with just an image and a title below it in a recycler view. For some reason my text view's that hold the title are getting cut off on the bottom.
See below:
I've tried setting the text view height to wrap_content but that will result in my images being pushed up and not consistently the same size across all items. Also I find it odd that the text view size & positioning doesn't even match the preview layout in android studios.
Any suggestions?
My view holder layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="#drawable/thumbnail_frame"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:weightSum="100"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="5:4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/thumbnail_item"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="80"
android:background="#color/dark_red"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/thumbnail_title"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="20"
android:ellipsize="end"
android:maxLines="2"
android:padding="8dp"
android:text="#string/title_place_holder"
android:textColor="#color/white"
android:textSize="12sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Why did you created a linear layout inside a constraint layout?
You can remove linear layout an put your ImageView and TextView directly inside constraint layout and constraint TextView top to bottom of ImageView
and instead of using weight you can use layout_constraintHeight_percent just like below:
app:layout_constraintHeight_percent="0.2"
But I recommend you not to use height_percant or weight and also avoid sizing the views width/height statically. it can cause problems on different screens
I think its better to remove LinearLayout and also remove weight and add this line to your ImageView:
app:layout_constraintDimensionRatio="H,5:4"
Write your TextView and ImageView like below:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="#drawable/thumbnail_frame"
android:paddingLeft="16dp"
android:paddingTop="12dp"
android:paddingRight="16dp"
android:paddingBottom="12dp">
<ImageView
android:id="#+id/thumbnail_item"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/dark_red"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,5:4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/thumbnail_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:padding="8dp"
android:text="#string/title_place_holder"
android:textColor="#color/white"
android:textSize="12sp"
app:layout_constraintTop_toBottomOf="#id/thumbnail_item"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I believe I have found the problem and it's the weight you're using in your LinearLayout.
Depending on the ImageView height (80) you have determined TextView height (20). Because of that TextView cannot wrap, so text is being cut from the bottom.
Solution 1: remove weight in linear layout and set image height to fixed height, and TextView to wrap_content. Just like below:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="5:4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/thumbnail_item"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/dark_red"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/thumbnail_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:padding="8dp"
android:text="#string/title_place_holder"
android:textColor="#color/white"
android:textSize="12sp" />
</LinearLayout>
Solution 2: You can remove padding in the TextView or set it to smaller one, but the problem might reoccur on smaller screens.
Make the weight of imageview to 60 and the weight of textview to 40. In short keep adjusting the weight attr value in order to solve your problem. Use thia solution only when you really need weight attr in your code. Or else, just remove weight and set the height to wrap_content for both of them.

Issue with ConstraintLayout (max width, dimension ratio and chain style)

I am having an issue with ConstraintLayout and a specific view.
What is wanted : 3 imageviews in a 6:5 ratio, the first one is bigger with the two other stacked vertically on its right. The whole view has a maxed width of 414dp.
When trying to set the horizontal chain style at packed, the views don't display at all over 414dp.
There is no issue under that limit or with a chain style other than packed.
Here are
the layout :https://gist.github.com/xcaEi/ba46e5e8c2d1d5682e1a5f3221325ed0
screenshots of the problem : https://imgur.com/a/0uZckj0
Am I missing something ?
To achieve what you want, I believe you must nest a ConstraintLayout inside another ConstraintLayout.
The problem is that you can't have both app:layout_constraintWidth_percent and layout_constraintWidth_max defined on the same view; each of these is one option for how to constrain a view set to "match constraints".
MATCH_CONSTRAINT dimensions (Added in 1.1)
When a dimension is set to MATCH_CONSTRAINT, the default behavior is to have the resulting size take all the available space. Several additional modifiers are available:
layout_constraintWidth_min and layout_constraintHeight_min: will set the minimum size for this dimension
layout_constraintWidth_max and layout_constraintHeight_max: will set the maximum size for this dimension
layout_constraintWidth_percent and layout_constraintHeight_percent: will set the size of this dimension as a percentage of the parent
(From https://developer.android.com/reference/android/support/constraint/ConstraintLayout)
You can work around this by having your inner ConstraintLayout specify its maximum width, and then have the ImageView children of that inner ConstrainLayout specify their percentages.
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#eee"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintWidth_max="414dp">
<ImageView
android:id="#+id/main_imageview"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:background="#caf"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintDimensionRatio="H,6:5"
app:layout_constraintWidth_percent="0.666"/>
<ImageView
android:id="#+id/second_imageview"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:background="#fac"
app:layout_constraintTop_toTopOf="#+id/main_imageview"
app:layout_constraintLeft_toRightOf="#+id/main_imageview"
app:layout_constraintBottom_toTopOf="#+id/third_imageview"
app:layout_constraintDimensionRatio="W,6:5"/>
<ImageView
android:id="#+id/third_imageview"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:background="#afc"
app:layout_constraintTop_toBottomOf="#+id/second_imageview"
app:layout_constraintLeft_toRightOf="#+id/main_imageview"
app:layout_constraintBottom_toBottomOf="#+id/main_imageview"
app:layout_constraintDimensionRatio="W,6:5"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
I think this is your need 3 imageview first one bigger. You can change layout_constraintHorizontal_weight properties check below
<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">
<ImageView
android:id="#+id/imageView9"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="6:5"
app:layout_constraintEnd_toStartOf="#+id/imageView10"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView10"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="6:5"
app:layout_constraintEnd_toStartOf="#+id/imageView11"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#+id/imageView9"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView11"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_orange_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="6:5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#+id/imageView10"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

Image Rows in Constraint Layout

Using constraints in a ConstraintLayout, I have created a layout as following:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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"
app:cardCornerRadius="2dp"
app:cardElevation="4dp"
app:cardUseCompatPadding="true">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp"
>
<ImageView
android:id="#+id/post_photo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:srcCompat="#drawable/ic_photo"
/>
<ImageButton
android:id="#+id/create_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:layout_constraintTop_toBottomOf="#+id/post_photo"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/share_button"
app:srcCompat="#drawable/ic_action_share"
android:scaleType="fitCenter"
/>
<ImageButton
android:id="#+id/share_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:layout_constraintTop_toBottomOf="#+id/post_photo"
app:layout_constraintLeft_toRightOf="#+id/create_button"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="#drawable/ic_action_share"
android:scaleType="fitCenter"
/>
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
My problem is that lower ImageButtons are not shown whenever height of image in ImageView is more than its width. If we hardcode a height (some kind of sufficient) on ConstraintLayout then buttons can get some height depending on the height of ImageView. I believe that the problem is when View Bounds are adjusted for ImageView. How can I overcome this situation?
wrap_content only asks the widget to measure itself, but won't limit its expansion against eventual constraints
add following attribute to your ImageView which is used when parent constraint layout set to wrap_content then there will be height measuring problem so overcome that
app:layout_constraintHeight_default="wrap"
and also set ImageView height to 0dp
<ImageView
android:id="#+id/post_photo"
android:layout_width="0dp"
app:layout_constraintHeight_default="wrap"
android:layout_height="0dp"
android:layout_marginTop="4dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:srcCompat="#drawable/ic_photo"
/>
for information same approach we can use in width problem
just replace width to 0dp and following property
app:layout_constraintWidth_default="wrap"
If you want to prevent this situation, you need to define percent or (dp) value.
1 - You can use maxWidth / maxHeight on ConstraintLayout like
<ImageView
...
android:maxHeight="192dp"
/>
2 - Also you can use Guideline like
<Guideline
id="guideLineMaxHeightOfImage"
guideLinePercent="0.4"
orientation="horizontal"
>
ImageView
<ImageView
...
app:layout_constraintTop_toTopOf="#+id/guideLineMaxHeightOfImage"
/>

Stretching ConstraintLayout and its content

I built a fragment (with ConstraintLayout), which looks like this:
Fragment image
I would like to reuse it, for example load it (add to fragmentManager) to an Activity's "fragment holder", but if this holder is too small, the images will cover each other.
See this:
Image problem
So, the images won't resize... Is there any solution to achieve the automatic resizing?
Thanks,
Zoltan
Place each of your ImageViews in their own ConstraintLayout. The layout_width and layout_height of the ImageViews should be wrap_content. The layout_width and layout_height of their parent ConstraintViews should be match_parent and wrap_content respectively.
Anchor the left ConstraintView to the top and start of the parent, and the right ConstraintView to the top and end using layout_constraintTop_toTopOf, layout_constraintStart_toStartOf, and layout_constraintEnd_toEndOf.
Also add the margins to the parent ConstraintViews using layout_marginTop and layout_marginLeft for the left; layout_marginTop and layout_marginRight for the right.
Next, create a vertical Guideline as a child of your fragment. Set its layout_constraintGuide_percent to 0.5. Give it an id of #+id/guideline.
Set the left ConstraintView's layout_constraintRight_toLeftOf to #+id/guideline, and the right ConstraintView's layout_constraintLeft_toRightOf to #+id/guideline as well.
This should scale the ImageViews sizes down if the fragment is not that wide.
If you want there to be a minimum gap between the two images, you can add layout_marginRight to the left ConstraintView, and layout_marginLeft to the right ConstraintView. Setting each to 2dp would give a minimum gap of 4dp.
Here is an example layout file. Edit the container ConstraintLayout's layout_width to see it in action:
<?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/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="100dp"
android:layout_height="300dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:background="#333333">
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/guideline"
app:layout_constraintGuide_percent="0.5"
android:orientation="vertical"/>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="16dp"
android:layout_marginLeft="16dp"
app:layout_constraintRight_toLeftOf="#+id/guideline"
android:layout_marginRight="2dp"
android:background="#FF0000">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="#mipmap/ic_launcher"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp"/>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
app:layout_constraintLeft_toRightOf="#+id/guideline"
android:layout_marginLeft="2dp"
android:background="#00FF00">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="#mipmap/ic_launcher"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

Categories

Resources