ConstraintWidth_percent looks different in design tab and in practice - android

I am trying to use ConstraintWidth_percent in my shop_list_item.xml, which is used inside my shopadapter. The problem I encounter is, that the design tab (how it should look like) and the in-app design (how it looks) are totally different. What am I doing wrong here?
How it should look like
How it looks
Code
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="#+id/mcv_product_item"
android:layout_width="0dp"
android:layout_height="210dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="#android:color/white"
app:cardCornerRadius="4dp"
app:cardElevation="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.40">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_product_image"
android:layout_width="match_parent"
android:layout_height="110dp"
android:contentDescription="TODO"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:loadImage="#{product.images[0]}"
tools:ignore="ContentDescription, HardcodedText"
tools:src="#drawable/ic_calibrate" />
<ImageView
android:id="#+id/iv_service_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="#null"
android:src="#drawable/ic_service"
app:hideView="#{product.hasService}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/tv_product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:maxLines="2"
android:text="#{product.name}"
android:textAlignment="textStart"
android:textColor="#color/color_text_dark"
android:textSize="#dimen/textDescriptionNormal1"
app:layout_constraintEnd_toEndOf="#+id/iv_product_image"
app:layout_constraintStart_toStartOf="#+id/iv_product_image"
app:layout_constraintTop_toBottomOf="#+id/iv_product_image"
tools:text="TEST TITLE TO ENSURE STUFF" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/tv_product_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="#{product.price}"
android:textColor="#color/color_text_blue"
android:textSize="#dimen/textHeadlineNormal1"
android:textStyle="italic|bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="#+id/tv_product_name"
tools:text="4870.00" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/tv_euro"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/currency"
android:textColor="#color/color_text_blue"
android:textSize="#dimen/textHeadlineNormal1"
android:textStyle="italic|bold"
app:layout_constraintBottom_toBottomOf="#+id/tv_product_price"
app:layout_constraintEnd_toEndOf="#+id/tv_product_name"
app:layout_constraintStart_toEndOf="#+id/tv_product_price"
app:layout_constraintTop_toTopOf="#+id/tv_product_price" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Currently not using -->
<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.30"/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.70"/>
</androidx.constraintlayout.widget.ConstraintLayout>
When I change constraintWidth_percent to something really high like 0.8, it works like it should (but looks weird in the design tab).

This is a normal behavior as the design preview of Android Studio can have different screen size than your mobile set or the emulator.. You can change the design preview width/height to have similar width/height like your testing emulator/mobile and you'll notice there is no change.
You can change this form:
This can be very obvious as your CardView apparently takes the 40% of the RecyclerView item width. You can notice this will the green guidelines in below pic.
What you can do is to teak the 40% until you feel comfortable with a certain width that can fits for the cart items.
Last thing you can try the below layout for aligning the item in the middle of the RecyclerView item 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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="#+id/mcv_product_item"
android:layout_width="0dp"
android:layout_height="210dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="#android:color/white"
app:cardCornerRadius="4dp"
app:cardElevation="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.4">
<!-- Add CardView items -->
</com.google.android.material.card.MaterialCardView>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.3" />
</androidx.constraintlayout.widget.ConstraintLayout>

Related

Constraint Layout Vertical Align Center - Two Child Views

I have two TextViews, one above the other. I would like the vertical middle of the two TextViews to be at the same position as the vertical middle of the ImageView. (This is so, regardless of the amount of text that may go into either TextView, everything will always look neat, vertically.)
I created what I need perfectly using two LinearLayouts (as the space above the title is the same as the space beneath the description):
But Android Studio was unable to covert it to ConstraintLayout successfully, as it just dumped the TextViews at the bottom of the layout. I've played with a lot of attributes, but could not quite arrive at the desired layout.
My question is similar to this one, except that I am trying to center_vertical align a pair of views rather than a single one - which means I have no view edge to align to the centre of the ImageView/container.
Is it possible to achieve what I'm after with ConstraintLayout? (I expect I may be able to do it with a single RelativeLayout, but I would like to use the layout_constraintDimensionRatio attribute on my ImageView which presumably leave me needing to use ConstraintLayout.)
In case it helps, here's the code for my aforementioned LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="#dimen/resources_list_image_size"
android:layout_height="#dimen/resources_list_image_size"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:layout_gravity="center_vertical"
android:contentDescription="#string/resource_image"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="#+id/textViewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/MyTextAppearanceMedium"
tools:text="Title" />
<TextView
android:id="#+id/textViewDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/MyTextAppearanceSmall"
tools:text="Description" />
</LinearLayout>
</LinearLayout>
Update: Solution
Thanks to Ben P's answer, this is my final code:
<?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">
<!-- Add guideline to align imageView to. -->
<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.3" />
<ImageView
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="#string/resource_image"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/guideline"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="#+id/textViewTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
app:layout_constraintBottom_toTopOf="#id/textViewDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/imageView"
app:layout_constraintTop_toTopOf="parent"
android:textAppearance="#style/MyTextAppearanceMedium"
app:fontFamily="#font/roboto_slab_regular"
app:layout_constraintVertical_chainStyle="packed"
tools:text="#string/enter_title_colon" />
<TextView
android:id="#+id/textViewDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/imageView"
app:layout_constraintTop_toBottomOf="#id/textViewTitle"
app:fontFamily="#font/roboto_slab_light"
android:textAppearance="#style/MyTextAppearanceSmall"
tools:text="Description" />
</androidx.constraintlayout.widget.ConstraintLayout>
It sounds like you could solve this problem by using a packed chain anchored to the top and bottom of the ImageView. You'll also need to use horizontal bias and a constrained width in order to get wrapping to work correctly.
<?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">
<View
android:id="#+id/anchor"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="64dp"
android:background="#caf"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="#id/anchor"
app:layout_constraintStart_toEndOf="#id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/two"/>
<TextView
android:id="#+id/two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_bias="0"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="#id/one"
app:layout_constraintStart_toEndOf="#id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#id/anchor"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The important attributes here are:
app:layout_constraintVertical_chainStyle="packed" on the first view, which causes the two textviews to stack right on top of each other
app:layout_constraintHorizontal_bias="0" on both views, which means that when the text is not long enough to reach the edge of the screen it will stick to the edge of the anchor view
app:layout_constrainedWidth="true" on both views, which prevents the textview from ever being wider than its constraints, and so the text wraps to a new line
If you want to use ConstraintLayout you could use something like this:
<?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">
<ImageView
android:id="#+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:contentDescription="description"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="#+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toTopOf="#+id/imageView">
<TextView
android:id="#+id/textViewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Title" />
<TextView
android:id="#+id/textViewDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Description" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
You can use this 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:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/colorAccent"
android:text="I am 5% of the screen height"
app:layout_constraintBottom_toTopOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="#+id/textView3"
app:layout_constraintHeight_percent="0.05"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="#+id/textView3"
app:layout_constraintTop_toTopOf="#+id/imageView2" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.15"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="#color/colorPrimary"
android:text="I am 15% of the screen height (And the image is 20% screen size in height) "
app:layout_constraintBottom_toBottomOf="#+id/imageView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView2"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.20"
app:layout_constraintDimensionRatio="1:1"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/rose" />
</android.support.constraint.ConstraintLayout>
It will look like this:
One important thing about this layout:
You can control your aspect ratio (for the image) with app:layout_constraintDimensionRatio="x:y" and by passing "1:1" make it square
And by the way - I am using support library for no reason on this example, you can use androidx

Bottom align not working in ConstraintLayout with different ImageView sizes

I want some different sized ImageViews in ConstraintLayout to have the same bottom line.
The smaller picture has the size: 100x140:
The larger picture has the size: 206x316:
With the xml 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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#8E8392">
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/jbean"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/p2"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p1"/>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/jellybig"
app:layout_constraintStart_toEndOf="#id/p1"
app:layout_constraintEnd_toStartOf="#+id/p3"
app:layout_constraintBottom_toBottomOf="#id/p1"
android:id="#+id/p2"
/>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/jellybig"
app:layout_constraintStart_toEndOf="#id/p2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#id/p2"
android:id="#+id/p3"
/>
</android.support.constraint.ConstraintLayout>
However it looks weird, as follows:
Update:
According to Tamir Abutbul's answer, I've updated the layout to:
<?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="200dp"
android:background="#8E8392">
<ImageView
android:layout_width="0dp"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintHeight_percent="0.99"
android:layout_height="0dp"
android:src="#drawable/jbean"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/p2"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p1"/>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintHeight_percent="0.99"
android:src="#drawable/jellybig"
app:layout_constraintStart_toEndOf="#id/p1"
app:layout_constraintEnd_toStartOf="#+id/p3"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p2"
/>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintHeight_percent="0.99"
android:src="#drawable/jellybig"
app:layout_constraintStart_toEndOf="#id/p2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p3"
/>
</android.support.constraint.ConstraintLayout>
Which I think it couldn't work as expected.
hey unable to add this xml as comment, this is the xml for above image
<?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="200dp"
android:background="#ffffff">
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/p2"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p1"
app:layout_constraintHorizontal_bias="1"/>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/big"
app:layout_constraintStart_toEndOf="#id/p1"
app:layout_constraintEnd_toStartOf="#+id/p3"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p2"
app:layout_constraintHorizontal_bias="1"
/>
<ImageView
android:id="#+id/p3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/big"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="#id/p2" />
</android.support.constraint.ConstraintLayout>
Try below 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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#8E8392">
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/jbean"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/p2"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p1"/>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/jellybig"
app:layout_constraintStart_toEndOf="#id/p1"
app:layout_constraintEnd_toStartOf="#+id/p3"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p2"
/>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/jellybig"
app:layout_constraintStart_toEndOf="#id/p2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/p3"
/>
</android.support.constraint.ConstraintLayout>
Let me know if not working
Your code will work for images with the same height and look like this:
But Different phones got different screen size, your images have fixed size and the result is that what may look good on one screen (your android studio preview screen) will not look good on another screen (your actual phone).
In ConstraintLayout you can work with percent on your views like this:
<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.6" //line 1
app:layout_constraintWidth_percent="0.5" //line 2
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
So what I did - I told my button to be equal to 60% of its parent in height (see line 1)
and also I told my button to be equal to 50% of its parent Width(see line 2).
You can implement this logic into your imageView to show different image size and keep a responsive layout.
do you want something like this??
I had a similar problem with an imageview that was constrained to the parents bottom but still showed some kind of margin. The solution was to add android:adjustViewBounds="true"

Android ConstraintLayout: Views not respecting margins

I am attempting to create a layout where various pieces of data are separated by a line (View), but the design requires an equal top and bottom spacing from the line. I am trying to use margins to accomplish this, but I am not getting the results I expected. Based on the official documentation, as long as the constraints are set for the margin direction, they should be respected. For some reason the top margin gives us the correct spacing, however the bottom margin does not give any spacing at all. I have created a sample containing only the pertinent layout axml to reproduce, along with a large enough margin to visualize the issue:
<?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="match_parent"
android:padding="20dp">
<TextView android:text="NAME"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_name_label"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<TextView android:text="Your Name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_name"
app:layout_constraintTop_toBottomOf="#+id/account_name_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<View
android:id="#+id/line1"
app:layout_constraintTop_toBottomOf="#+id/account_name"
app:layout_constraintBottom_toTopOf="#+id/account_joined_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="#000000"
android:layout_marginTop="100dp"
android:layout_marginBottom="100dp"
/>
<TextView android:text="JOINED"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_joined_label"
app:layout_constraintTop_toBottomOf="#+id/line1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<TextView android:text="January 1, 2019"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_joined"
app:layout_constraintTop_toBottomOf="#+id/account_joined_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
The above results in the following, visually:
Now, I can add the android:layout_marginTop="100dp" to the first TextView after the line View to "fix" this, however I want to reuse the styles for the line View, without having to worry about remembering to add a top margin to whatever happens to be the first View after the line View. What am I missing?
Update: Here is what the layout SHOULD look like:
You need to connect the bottom of account_joined to the bottom of parent and the bottom of account_joined_label to the top of account_joined. So you can try this one:
<?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:padding="20dp">
<TextView android:text="NAME"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_name_label"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView android:text="Your Name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_name"
app:layout_constraintTop_toBottomOf="#+id/account_name_label"
app:layout_constraintRight_toRightOf="parent" />
<View
android:id="#+id/line1"
app:layout_constraintTop_toBottomOf="#+id/account_name"
app:layout_constraintBottom_toTopOf="#+id/account_joined_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="#000000"
android:layout_marginTop="100dp"
android:layout_marginBottom="100dp"/>
<TextView android:text="JOINED"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_joined_label"
app:layout_constraintTop_toBottomOf="#+id/line1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="#+id/account_joined" />
<TextView android:text="January 1, 2019"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/account_joined"
app:layout_constraintTop_toBottomOf="#+id/account_joined_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Some info before the code:
When you use something like android:layout_marginTop="100dp" you are making your layout to a non-responsive one.
Why: In android, different phones got dofferent screen size and what may look good on 1 device with 100dp margin may not look good on another device.
So if possible try not to use large values as fixed sizes, the next part of the question will explain how to handle this.
Here is where the fun begins:
You can simply use Guidelines to fix your margin problems - it will be responsive to all screen sizes and won't have hardcoded value like 120dp.
All you have to do is to constraint "NAME" to the top constraint and "JOINED" to the bottom constraint like this:
<?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">
<TextView
android:id="#+id/account_name_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="NAME"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline9" />
<TextView
android:id="#+id/account_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="Your Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/account_name_label" />
<View
android:id="#+id/line1"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginStart="8dp"
android:background="#000000"
app:layout_constraintBottom_toTopOf="#+id/account_joined_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/account_name" />
<TextView
android:id="#+id/account_joined_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="JOINED"
app:layout_constraintBottom_toTopOf="#+id/guideline8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="#+id/account_joined"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="January 1, 2019"
app:layout_constraintBottom_toTopOf="#+id/account_joined_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<android.support.constraint.Guideline
android:id="#+id/guideline8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.85" />
<android.support.constraint.Guideline
android:id="#+id/guideline9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.15" />
</android.support.constraint.ConstraintLayout>
And it will look like this:
Now don't be scared, your layout looks ok - it's just my lame lame skills in editing photos (check this on your device).
The important thing is that you can change the look of your layout by changing the value of this line in your guidelines:
app:layout_constraintGuide_percent="0.15"
If anything was not understandable feel free to ask.

RecyclerView don't clip item in the corner

I want to make recyclerView round corner but seem like if the child item has background color, it will cover to the recyclerView and couldn't be clipped. Here is the design
If I remove the background color of item, then it could be like my design. But unfortunately, sometime it has blue background
Here is what my app show
Here is my item layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item_popover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/dp_8"
android:background="#color/white"
tools:ignore="RtlHardcoded,RtlSymmetry"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.jp.base.customView.AppImageView
android:id="#+id/img_notification"
android:paddingRight="#dimen/dp_8"
app:srcCompat="#mipmap/ic_launcher_round"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="#dimen/dp_8"
android:layout_marginEnd="#dimen/dp_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v7.widget.AppCompatImageView
android:id="#+id/img_arrow"
app:srcCompat="#drawable/ic_keyboard_arrow_right_blue_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.jp.base.customView.AppTextView
android:id="#+id/tv_message"
tools:text="Message....\nMessage"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/img_notification"
app:layout_constraintEnd_toStartOf="#id/img_arrow"
android:maxLines="5"
android:layout_marginTop="#dimen/dp_5"
android:textColor="#color/black"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<com.jp.base.customView.AppTextView
android:id="#+id/tv_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dp_8"
android:drawablePadding="#dimen/dp_8"
android:gravity="center_vertical"
android:textSize="#dimen/text_small"
app:app_leftDrawable="#drawable/ic_access_time_black_24dp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/img_arrow"
app:layout_constraintStart_toEndOf="#id/img_notification"
app:layout_constraintTop_toBottomOf="#+id/tv_message"
app:layout_constraintVertical_bias="100"
tools:text="a month ago" />
<View
app:layout_constraintTop_toBottomOf="#id/tv_time"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="#dimen/dp_8"
android:background="#color/gray"
android:layout_width="0dp"
android:layout_height="0.5dp" />
</android.support.constraint.ConstraintLayout>
My RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="#+id/list_notification"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="-30dp"
android:background="#drawable/rect_bound_bottom_5dp"
android:clipChildren="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_popup_title"
tools:listitem="#layout/item_popover" />
I would try:
Setting "round rect" Outline on the Recycler View - setOutline
This is usually used to provide a shadow effect together with "elevation" but if you don't need a shadow - you can skip the elevation part
Finally call setClipToOutline again on the RecyclerView
Most easy solution will be
Just wrap your RecyclerView inside CardView.
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:cardCornerRadius="50dp"
tools:cardElevation="0dp">
<android.support.v7.widget.RecyclerView
...
/>
</android.support.v7.widget.CardView>
Use cardCorderRadius to change corner radius.

Dynamic views in Constraint Layout

I have a RecyclerView with CardView as its items.
Below is the layout for my main activity.
<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"
tools:context="com.example.personal.newz.ui.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"></android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
And below is the layout for my recycler view items
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="16dp"
card_view:cardCornerRadius="4dp"
>
<android.support.constraint.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.Guideline
android:id="#+id/vertical_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.6" />
<TextView
android:id="#+id/date_tv"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="2 hours ago" />
<TextView
android:id="#+id/source_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="#id/date_tv"
app:layout_constraintTop_toTopOf="#id/date_tv"
tools:text="BBC News" />
<TextView
android:id="#+id/headline_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="32dp"
android:maxLines="2"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/vertical_guideline"
app:layout_constraintTop_toBottomOf="#id/date_tv"
tools:text="Apple admits slowing down older iphones" />
<TextView
android:id="#+id/description_tv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:maxLines="4"
app:layout_constraintLeft_toLeftOf="#id/date_tv"
app:layout_constraintRight_toLeftOf="#id/vertical_guideline"
app:layout_constraintTop_toBottomOf="#id/headline_tv"
tools:text="Customers have long suspected iPhones slow down over time. Now, Apple has confirmed some models do." />
<ImageView
android:id="#+id/article_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitXY"
app:layout_constraintHorizontal_bias=".7"
app:layout_constraintLeft_toRightOf="#id/vertical_guideline"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/source_tv"
tools:src="#drawable/placeholder" />
<ImageView
android:id="#+id/bookmark_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:src="#drawable/bookmark"
app:layout_constraintEnd_toStartOf="#+id/share_image"
app:layout_constraintStart_toEndOf="#+id/vertical_guideline"
app:layout_constraintTop_toBottomOf="#id/article_image"
app:layout_constraintHorizontal_chainStyle="packed"/>
<ImageView
android:id="#+id/share_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/share_icon"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/bookmark_image"
app:layout_constraintTop_toBottomOf="#id/article_image" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
Now when I first start my app the individual cardview's width don't match to the parent and kind of behave like their width is wrap content. After a few seconds the width of all the cardviews adjusts itself to match the parent.
ConstraintLayout does not actually support match_parent for its children. If you try to use match_parent, sometimes it will work, and sometimes it will not. Android Studio is also sort of weird about match_parent, and sometimes will allow it and sometimes will automatically replace it with a hardcoded value that matches the last emulator you ran. Regardless, do not use match_parent for children of a ConstraintLayout.
Instead of android:layout_width="match_parent", use this:
android:layout_width="0dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
Instead of android:layout_height="match_parent", use this:
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
When I make these changes to your RecyclerView tag, the problem goes away.

Categories

Resources