Dynamic views in Constraint Layout - android

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.

Related

ConstraintWidth_percent looks different in design tab and in practice

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>

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

Constraint Layout - Placing a Viewpager above another view

I am trying to place a Viewpager above another view in constraint layout, however the Viewpager extends all the way to the bottom of parent unless I use a set height such as "150dp". How would I make it so that it only extends until it reaches the top of the "Create a new account" Layout?
Things I have tried:
-Making height of viewpager a set amount of dp (150dp), it works but I prefer to make it match multiple device heights
-Adding constraints Constraint Bottom of Viewpager to top of Create Account Layout, doesn't work
Here is my code for the layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fillViewport="true">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:id="#+id/appname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="MyApp"
android:textColor="#color/colorBlackFont"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2"/>
<TextView
android:id="#+id/textview_betterexperience"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text=""
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/appname"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:drawablePadding="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="48dp"
android:layout_marginEnd="8dp"
android:hint="Username"
android:textSize="14dp"
android:textCursorDrawable="#drawable/cursor_color"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/textview_betterexperience"
app:layout_constraintWidth_percent=".75"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="1">
<View
android:id="#+id/divider_bottom"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/dividerColor"
android:layout_alignParentTop="true"/>
<TextView
android:id="#+id/textview_newaccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="Create a new account"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textStyle="bold" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
</ScrollView>
The end result I want it to look like would be like this:
app:layout_constraintBottom_toTopOf="#id/unnamed_relativeLayout"
app:layout_constrainedHeight="true" (or set layout_height to 0dp)
The preview might be weirded out but will display once inflated with content in app
Add an id to your Relative layout
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="1">
Then in your viewpager add
app:layout_constraintBottom_toTopOf="#id/relativeLayout"
and set android:layout_height="0dp" so it matches the constraints.
You are missing the bottom constraint for view pager . Use below
app:
layout_constraintBottom_toTopOf="#id/relativeLayoutId"

ScrollView in ConstrainLayout scrolled wrong

I have this layout:
<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=".MainActivity">
<android.support.constraint.Guideline
android:id="#+id/bottomGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.95"/>
<ImageView
android:id="#+id/logo"
android:layout_width="144dp"
android:layout_height="52dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/tvTitle"
app:layout_constraintVertical_chainStyle="packed"
android:src="#drawable/ic_launcher_background"/>
<TextView
android:id="#+id/tvTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="28dp"
app:layout_constraintTop_toBottomOf="#+id/logo"
app:layout_constraintStart_toStartOf="#id/btnGooglePlay"
app:layout_constraintEnd_toEndOf="#id/btnGooglePlay"
app:layout_constraintBottom_toTopOf="#id/tvText"
app:layout_constraintVertical_chainStyle="packed"
android:text="Title!"
/>
<TextView
android:id="#+id/tvText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="28dp"
android:gravity="center"
app:layout_constraintTop_toBottomOf="#id/tvTitle"
app:layout_constraintStart_toStartOf="#id/btnGooglePlay"
app:layout_constraintEnd_toEndOf="#id/btnGooglePlay"
app:layout_constraintBottom_toTopOf="#id/scroll"
app:layout_constraintVertical_chainStyle="packed"
android:text="Many test about something.\nMany test about something Many test about something Many test about something"
/>
<ScrollView
android:id="#+id/scroll"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/tvText"
app:layout_constraintStart_toStartOf="#id/btnGooglePlay"
app:layout_constraintEnd_toEndOf="#id/btnGooglePlay"
app:layout_constraintBottom_toTopOf="#id/btnGooglePlay"
app:layout_constraintVertical_chainStyle="packed"
>
<LinearLayout
android:id="#+id/containerFeature"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"/>
</ScrollView>
<android.support.v7.widget.CardView
android:id="#+id/btnGooglePlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toTopOf="#id/bottomGuideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="#color/colorPrimary"
app:cardElevation="4dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:background="#color/colorPrimary"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Push this"
android:textAllCaps="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_gravity="center"
android:text="some description"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
I want the icon(R.id.logo) to be closer to the center if there are not many items in containerFeature. Like on this picture:
and if there are more items, icon must be closer to the top:
but if there are to many items, I expect that ScrollView will be work.
And I will see this:
If I change ScrollView attribute layout_height to "0dp" I see that all works fine, but icon always up and chainStyle="packed" have no sense for me.
What can I do to fix ScrollView behavior with chainStyle="packed?
By default, if a dimension of a View is set to wrap_content its constraints are not enforced when it gets too big to satisfy them. In order to change that behavior and have them enforced you need to add app:layout_constrainedHeight="true" to your ScrollView.
Documentation:
WRAP_CONTENT : enforcing constraints (Added in 1.1)
If a dimension is set to WRAP_CONTENT, in versions before 1.1 they will be treated as a literal dimension -- meaning, constraints will not limit the resulting dimension. While in general this is enough (and faster), in some situations, you might want to use WRAP_CONTENT, yet keep enforcing constraints to limit the resulting dimension. In that case, you can add one of the corresponding attribute:
app:layout_constrainedWidth=”true|false”
app:layout_constrainedHeight=”true|false”

app:layout_marginBottom is not working well with android constraint layout

Is there any reason why the following layout_marginBottom is not working?
However, if I use layout_marginTop on the second view it does work 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="match_parent"
android:background="#ade4ad">
<TextView
android:id="#+id/first"
android:layout_width="90dp"
android:layout_height="40dp"
app:layout_marginBottom="10dp"
android:background="#000"/>
<TextView
android:id="#+id/second"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#fff"
app:layout_constraintTop_toBottomOf="#+id/first"/>
</android.support.constraint.ConstraintLayout>
In order to
android:layout_marginBottom="20dp"
work well, you should use
app:layout_constraintBottom_toBottomOf="parent"
Layout top/bottom margin works only when:
constraints in the same direction need to connect with their next neighbor child, like a unidirectional linked list.
last constraint in the direction must be set.
In your case, you need to set "layout_constraintBottom_toXXXXX" for each view in the chain, and last view set bottom to parent.
<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="#ade4ad">
<TextView
android:id="#+id/first"
android:layout_width="90dp"
android:layout_height="40dp"
app:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="#+id/second"
android:background="#000"/>
<TextView
android:id="#+id/second"
android:layout_width="90dp"
android:layout_height="40dp"
app:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="#+id/third"
android:background="#fff"/>
<TextView
android:id="#+id/third"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#fff"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
Moreover, reverse dependency is not required except you want "layout_marginTop" works.
you can use that trick, create a space bellow, align to parent bottom
<Space
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="80dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
and align your view on top of the space
app:layout_constraintBottom_toTopOf="#+id/space"
like so
<TextView
android:id="#+id/howNext"
style="#style/white_action_btn_no_border"
android:layout_width="344dp"
android:layout_height="60dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="#string/got_it_next"
app:layout_constraintBottom_toTopOf="#+id/space"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
This is not LinearLayout or RelativeLayout, its ConstraintLayout so you have to give Left, Right, Bottom, Top Constraint to Relevant Layout, in your case You have to give TextView first Bottom_Top Constraint to TextView second. so you can get Margin between Two TextView.
Your layout should be like below.
<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"
android:background="#ade4ad">
<TextView
android:id="#+id/first"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="#+id/second"
android:layout_width="90dp"
android:layout_height="40dp"
android:background="#fff"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="#+id/first"
app:layout_constraintLeft_toLeftOf="#+id/first"
app:layout_constraintRight_toRightOf="#+id/first" />
</android.support.constraint.ConstraintLayout>

Categories

Resources