set background when using constraint layout - android

I am using constraint layout as parent, and added multiple child using constraint. There are three views horizontally and I have to apply rounded corner background for two view only, which was achieved by linear layout previously. But with the help of constraint layout, I am not able to achieve this.
How can I achieve this?

ConstraintLayout recently introduced the concept of constrainthelper which can be used to perform an action on a group of views. 'Group', which is used to toggle visibility of multiple view is subclass of this.
A constrainthelper which changes background of multiple views together is not yet a part of the stable release, but soon will be.
Until then, you can achieve a backround as in the example below, where 3 textview share a common background, using an View class:
<?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"
android:background="#AAA">
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FFF"
app:layout_constraintBottom_toBottomOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toTopOf="#+id/textView1" />
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toBottomOf="#+id/textView1"
tools:text="TextView" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toBottomOf="#+id/textView2"
tools:text="TextView" />
</android.support.constraint.ConstraintLayout>
EDIT: A nice blog on what to expect from ConstraintLayout 2.0

You can do it with simple Image View following this steps:
Put a Image view before text views
set Image view's start, top constraint to match first text view
Set Image view's end & bottom constraint to match last text views
This will gone stretch that imageview to a Rectangle defined by top-left of first view and bottom-right of last view.
Note that ImageView must be before text views:
<!--Background Image View-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="#drawable/lake"
app:layout_goneMarginRight="#dimen/activity_vertical_margin"
<!--Top_LEFT by first view-->
app:layout_constraintStart_toStartOf="heding"
app:layout_constraintTop_toTopOf="#+id/heding"
<!--BOTTOM RIGHT by last view-->
app:layout_constraintEnd_toEndOf="#+id/info"
app:layout_constraintBottom_toBottomOf="#+id/info"
/>
<!--first view-->
<TextView
android:id="#+id/heding"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Lake Tahoe "
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintStart_toEndOf="#+id/thumb"
app:layout_constraintTop_toTopOf="#+id/thumb"
tools:layout_constraintBottom_creator="1"
android:textColor="#FFF"
tools:layout_constraintTop_creator="1" />
<!--last view-->
<TextView
android:id="#+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="LakeTahoe is a large freshwater lake in Sierra Naveda"
android:textSize="15sp"
android:textColor="#FFF"
app:layout_constraintBottom_toBottomOf="#+id/thumb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintStart_toEndOf="#+id/thumb"
app:layout_constraintTop_toBottomOf="#+id/heding"
app:layout_constraintVertical_bias="1.0"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />
Result:

Related

Android display a square image view next to two stacked views

I am trying to display an image view next a label and a text box. The end result should look like this:
The height of the image view should be the same as whatever space the label and the text box take up and the width should be the same as the height so it is a square.
I have looked at this question to make an image view with equal width and height.
I have also looked at this other question which is similar to mine but using weightSum and layout_weight made the image view take up too much space or become distorted. I have also tried combining answers from the two questions but nothing worked.
You can achieve this very simply using ConstraintLayout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f4f4f4"
tools:context="MainActivity">
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.3"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.3"
android:elevation="6dp"
android:layout_margin="8dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintBottom_toBottomOf="#+id/button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/button2"
android:background="#color/colorAccent"/>
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:elevation="6dp"
android:layout_marginLeft="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView2"
app:layout_constraintTop_toTopOf="#+id/imageView2" />
<EditText
android:id="#+id/editText4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:elevation="6dp"
android:ems="10"
android:layout_marginLeft="8dp"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintBottom_toBottomOf="#+id/imageView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
This will look like this
The important attributes:
To make your image square:
app:layout_constraintDimensionRatio="1:1"
To make your views responsive:
app:layout_constraintWidth_percent
app:layout_constraintHeight_percent
Together with:
android:layout_width="0dp"
android:layout_height="0dp"
To make your views over the container so it looks like they are inside it (in this example I have used a button but feel free to use any kind of view)android:elevation="6dp"

ConstraintLayout Prevent Overlap of Top and Bottom Widgets

I am trying to create a layout with three groups of widgets. I want one group constrained to the top, one to the bottom, and one to float in the middle of the space between the two groups. The layout will be used in a fragment, so it could become squashed, especially when the keyboard is shown. I am having trouble figuring out how to prevent overlap of the two groups, while keeping the top and bottom constrained to the top and bottom of the layout.
I thought of several ways to do it, but I couldn't figure out how to implement any of the properly.
Using app:layout_constraintVertical_bias or app:layout_constraintVertical_weight to pull widgets together or spread them apart.
Using one chain, but having breaks in between the groups. I couldn't figure out how to split the chain part way through to allow the different groups to spread out.
Specify a minimum height that is dependent upon the contained widgets. (It will be contained in a ScrollView so it if the height is constrained it will work)
Create groups of packed chains where the packed chains are in a spread chain.
Or is there a better way than these to get what I want?
Note: I would prefer that the top and bottom groups aren't right against the parent layout, but I couldn't figure out how to get those groups to dynamically distance themselves from the parent layout without also spreading the group apart. I want the top and bottom groups close to the parent layout, but not necessarily right against it. It is better to have them right against the parent layout than close to the middle. Ideally I would be able to use app:layout_constraintVertical_bias or app:layout_constraintVertical_weight for this.
Code
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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" >
<EditText
android:id="#+id/edit_text_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/edit_text_horizontal_margin"
android:layout_marginRight="#dimen/edit_text_horizontal_margin"
android:layout_marginTop="#dimen/edit_text_vertical_margin"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/edit_text_2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:hint="Edit Text 1"
android:selectAllOnFocus="true" />
<EditText
android:id="#+id/edit_text_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/edit_text_horizontal_margin"
android:layout_marginRight="#dimen/edit_text_horizontal_margin"
android:layout_marginTop="#dimen/edit_text_vertical_margin"
android:layout_marginBottom="#dimen/edit_text_vertical_margin"
app:layout_constraintTop_toBottomOf="#id/edit_text_1"
app:layout_constraintBottom_toTopOf="#id/button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:hint="Edit Text 2"
android:selectAllOnFocus="true" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/edit_text_2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:enabled="false"
android:text="Button" />
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/progress_bar_margin"
app:layout_constraintTop_toBottomOf="#id/button"
app:layout_constraintBottom_toTopOf="#id/clickable_text_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:visibility="gone" />
<TextView
android:id="#+id/clickable_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/text_button_horizontal_margin"
android:layout_marginRight="#dimen/text_button_horizontal_margin"
android:layout_marginTop="#dimen/text_button_vertical_margin"
android:layout_marginBottom="#dimen/text_button_vertical_margin"
android:paddingLeft="#dimen/text_button_horizontal_margin"
android:paddingRight="#dimen/text_button_horizontal_margin"
android:paddingTop="#dimen/text_button_vertical_margin"
android:paddingBottom="#dimen/text_button_vertical_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="Clickable Text View"
android:clickable="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Images
- - - -
Here is what I have, and how I want it to look. - - - - - Here is the overlapping problem.
for the textview add a constraint top to bottom of the button ie app:layout_constraintTop_toBottomOf="#+id/button". IMO always constraint all 4 angles wherever possible; start top end bottom. In that way when your view is 'squashed', it will still adhere to the constraint set
Here, try 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"
tools:context=".MainActivity">
<EditText
android:id="#+id/emailId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="36dp"
android:hint="Enter email ID"
android:inputType="textEmailAddress"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="36dp"
android:hint="Enter password"
android:inputType="textPassword"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/emailId" />
<Button
android:id="#+id/signInBtn"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="#color/colorAccent"
android:text="Sign in"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/password" />
<TextView
android:id="#+id/analyticsLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:text="Click me to create a log"
android:textColor="#android:color/holo_blue_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I believe that you can use Guidelines together with app:layout_constraintHeight_percent to solve your problem.
Consider this 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="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:enabled="false"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/guideline3"
app:layout_constraintHeight_percent="0.1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/edit_text_2" />
<EditText
android:id="#+id/edit_text_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:hint="Edit Text 2"
android:selectAllOnFocus="true"
app:layout_constraintBottom_toTopOf="#id/button"
app:layout_constraintHeight_percent="0.1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/edit_text_1" />
<EditText
android:id="#+id/edit_text_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:hint="Edit Text 1"
android:selectAllOnFocus="true"
app:layout_constraintBottom_toTopOf="#id/edit_text_2"
app:layout_constraintHeight_percent="0.1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="#id/clickable_text_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/button" />
<TextView
android:id="#+id/clickable_text_view"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:clickable="true"
android:gravity="center"
android:text="Clickable Text View"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".35" />
Every view height is equal to 10% of the screen height, that's because of the app:layout_constraintHeight_percent="0.1" attribute. This will solve the overlapping problem for you because you will be able to tell your view what height to be relative to the screen size.
I was using guidelines as well with the app:layout_constraintGuide_percent=".35" attribute to tell the guideline were to be on the screen, by doing that I can constrain different views to it and you won't have to stick your views to the top of bottom of the screen as you mentioned (I would prefer that the top and bottom groups aren't right against the parent layout)
Your layout will look like this:(this is preview image for better understanding guidelines)
for who has same problem. use app:layout_constraintVertical_chainStyle="packed" with app:layout_constraintVertical_bias="1" to attach the view to botom. if use app:layout_constraintVertical_bias="0"the view will attach to top.
<TextView
...
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="1"/>

ImageView inside ConstraintLayout does not work

I have a problem with correct display of ImageView. I want to display ImageView inside ConstraintLayout. On preview it looks exactly as i need, but when i'm starting it on device it looks completly dirrerent. This layout is places inside recycle view. What is wrong with this code?
<?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"
android:id="#+id/promotionRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="10dp"
android:background="#fff"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<android.support.constraint.ConstraintLayout
android:id="#+id/promotionImageLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintHeight_default="spread"
android:background="#color/colorPrimary">
<ImageView
android:id="#+id/promotionImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="#mipmap/ic_start_promotion"
android:background="#mipmap/ic_start_promotion"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHeight_min="150dp" />
<ImageView
android:id="#+id/fadeGradientImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#drawable/fade_image_background" />
<TextView
android:text="Sample title"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="6dp"
android:textColor="#ffffff"
android:id="#+id/promotionNameTextView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>
<TextView
android:id="#+id/promotionDescriptionTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp"
android:layout_marginTop="12dp"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:text="Sampe description" />
</LinearLayout>
EDIT: Deep explanation:
I want to create row for RecycleView. Each row have to contains image, title and description. Title have to be in the left bottom corner of the image. Description have to be below the image. After that i have to put gradient (black in the bottom) into the image. Screen with "Preview" is exactly what i need.
EDIT2: Everything with this layout is ok. It is working as expected, i forget that i made some changes in kotlin code... Sory for problem.
First things first, every view should apply the attribute rules of its parent ViewGroup. ConstraintLayout doesn't support match_parent. It supports the 0dp value which means "match constraint". This way the view will expand to fill the constraint bounded space.
Next, ConstraintLayout was created to achieve a flat view hierarchy for better layout performance. So, never nest it inside a LinearLayout as it has the chains feature to get the same behavior in a more flexible way. Plus, you can achieve the structure with a ConstraintLayout at the top level .
Another thing, If you are going to define the same margin in all directions, you can just use layout_margin.
Finally, you have overdraw problems. ConstraintLayout is flexible enough to allow us to position views as backgrounds and help us avoid overlapped backgrounds.
Here's a solution:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/promotionRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="#+id/promotion_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/promotion_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#mipmap/ic_start_promotion"
app:layout_constraintHeight_min="150dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/shadow"
android:layout_width="0dp"
android:layout_height="80dp"
android:adjustViewBounds="true"
android:background="#drawable/fade_image_background"
app:layout_constraintBottom_toBottomOf="#+id/promotion_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="#+id/promotion_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="Sample title"
android:textColor="#android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#+id/promotion_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="#+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:padding="12dp"
android:text="Sampe description"
android:textSize="13sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/promotion_image" />
</android.support.constraint.ConstraintLayout>
Try it. Hope this helps!
First of all, trying to write more presicely what do you want? Display image view inside layout it's somthing common words. As for your code, beside you don't have any constraints. You have strange view height, for second ImageView:
android:layout_height="match_parent"
It may overlay all other children view, it's very strange parameter.

How to give background color to Group in Constraintlayout

I have grouped 3 textview in a constraint layout. I have background to the group, but its not working.
<android.support.constraint.Group
android:id="#+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/text_color_3"
app:constraint_referenced_ids="price_tv,currency_unit_tv,frequency_tv" />
Is there anyway other round to do it.
According to the documentation, Group is only used for controlling the visibility of a set of widgets.
You can set the background to a View and constrain the view to how you desire the background to appear.
In the code sample below, after setting the background to the View with ID background, I constrained the top, left and right sides of the view to the parent and the bottom of the view to the last TextView in the group, which in this case is the TextView with ID textView3. I also added a 16dp bottom padding to textView3 so the background doesn't look weird. You could also use a Guideline for this.
Also note that the view background needs to be added before the group of views that need the background. If it's placed after the group of views, the background would be drawn over the group (and that's not what you want).
<?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:background="#444444">
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FFFFFF"
app:layout_constraintBottom_toBottomOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView 1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView1"/>
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:paddingBottom="16dp"
android:text="TextView 3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2"/>
</android.support.constraint.ConstraintLayout>
I hope this helps.
Though the group is only for visibility purpose but you can easily put a background to group.
Group view doesn't have any width and height, so wrap content wouldn't be visible on actual screen.
Provide constraints to Group view and set background attributes.
Eg:
<android.support.constraint.Group
android:id="#+id/group"
android:layout_width="0dp" //match constraint
android:layout_height="0dp" //match constraint
android:background="#color/text_color_3"
app:constraint_referenced_ids="price_tv,currency_unit_tv,frequency_tv"
app:layout_constraintBottom_toBottomOf="#+id/frequency_tv"
app:layout_constraintEnd_toEndOf="#+id/price_tv"
app:layout_constraintStart_toStartOf="#+id/price_tv"
app:layout_constraintTop_toTopOf="#+id/price_tv" />
//below are your TextViews aligned vertically
<TextView android:id="#+id/price_tv"/>
<TextView android:id="#+id/currency_unit_tv" .../>
<TextView android:id="#+id/frequency_tv" .../>
Hope it helps :)
Group is useful for the visibility purpose in ConstraintLayout. ConstraintLayout is introduced to remove the hierarchy of the multiple ViewGroups(Layouts).
We can simply use for the background purpose. If you simply have 3 TextView and want to apply the background color to the TextView don't add it to any ViewGroup(Layout), just check 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"
android:background="#AAA">
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FFF"
app:layout_constraintBottom_toBottomOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toTopOf="#+id/textView1" />
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toBottomOf="#+id/textView1"
tools:text="TextView" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toBottomOf="#+id/textView2"
tools:text="TextView" />
</android.support.constraint.ConstraintLayout>
Result:
You can find the source here
Group is only used for controlling the visibility of Referenced Ids in app:constraint_referenced_ids. According to the documentation. Solution is just put views in a Viewgroup. I had to put all the views in ConstraintLayout to constrol the visibility + benefits of chaining views in CL.
<android.support.constraint.ConstraintLayout
android:id="#+id/area_range_constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
visibility = "View.VISIBLE"
>
<TextView
android:id="#+id/area_title_tv"
style="#style/filter_heading_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/STR_AREA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/area_range_from"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:hint="#string/STR_MIN_AREA"
android:inputType="number"
android:maxLength="10"
android:text='#{searchQueryModel.areaMin==null ? "": StringUtils.getDelimeterString(String.valueOf(safeUnbox(searchQueryModel.getAreaMin())))}'
android:textAlignment="center"
android:textDirection="anyRtl"
android:textSize="14sp"
app:layout_constraintEnd_toStartOf="#+id/textView254"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/area_title_tv" />
<EditText
android:id="#+id/area_range_to"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:hint="#string/STR_MAX_AREA"
android:inputType="number"
android:maxLength="10"
android:text='#{searchQueryModel.areaMax==null ? "": StringUtils.getDelimeterString(String.valueOf(safeUnbox(searchQueryModel.getAreaMax())))}'
android:textAlignment="center"
android:textDirection="anyRtl"
android:textSize="14sp"
app:layout_constraintBaseline_toBaselineOf="#+id/textView254"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/textView254" />
<TextView
android:id="#+id/textView254"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/STR_TO"
android:textColor="#color/text_color_3"
android:textSize="#dimen/text_size_normal"
app:layout_constraintBaseline_toBaselineOf="#+id/area_range_from"
app:layout_constraintEnd_toStartOf="#+id/area_range_to"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/area_range_from" />
<TextView
android:id="#+id/area_range_value_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text='#{`(` + areaUnit + `)`}'
android:textColor="#color/colorPrimary"
android:textSize="#dimen/text_size_normal"
app:layout_constraintBottom_toBottomOf="#+id/area_title_tv"
app:layout_constraintStart_toEndOf="#+id/area_title_tv"
app:layout_constraintTop_toTopOf="#+id/area_title_tv" />
</android.support.constraint.ConstraintLayout>
Use the new Layer that was introduced in ConstraintLayout 2
As per the official documentation, group is only used to control the visibility and you cannot change the background of the views of a particular group.
Documentation: This class controls the visibility of a set of referenced widgets. Widgets are referenced by being added to a comma separated list of ids.
To change it dynamically, use for all the three TextViews.
textView.setBackgroundColor(Color.RED);
or
textView..setBackgroundColor(Color.parseColor("#ffffff"));

Text wrapping in Constraint layout

Trying to make a really simple layout for a settings page using ConstraintLayout.
Simple text views to the left one below the other and a switch to the right to the center.
The layout I have works fine for newer devices, but as soon I switch to a Nexus 4 or older, the switch goes below/disappears from the view.
Here is my layout code,
<android.support.constraint.ConstraintLayout
android:id="#+id/locationLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="parent">
<TextView
android:id="#+id/locationTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="#string/location_title"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="#id/guidelineLocationLayout"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textSize="16sp"/>
<TextView
android:id="#+id/locationDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/location_description"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationTitle"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="#id/locationTitle"
app:layout_constraintRight_toLeftOf="#id/guidelineLocationLayout"
android:textSize="12sp"
/>
<Switch
android:id="#+id/locationPermissionSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#id/guidelineLocationLayout"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="parent"/>
<View
android:id="#+id/viewLocationLayout"
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="#d6d6d6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationDescription"/>
<android.support.constraint.Guideline
android:id="#+id/guidelineLocationLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="48dp" />
</android.support.constraint.ConstraintLayout>
And here are how the constraints look like for the Pixel 2XL,
Here is how they look on a smaller device,
I have used 0dp width for the long description and defined left and right constraints, anything else I could do?
You can use barriers instead of guidelines because a Barrier references multiple widgets as input, and creates a virtual guideline based on the most extreme widget on the specified side.
According to the Documentation
Similar to a guideline, a barrier is an invisible line that you can
constrain views to. Except a barrier does not define its own position;
instead, the barrier position moves based on the position of views
contained within it. This is useful when you want to constrain a view
to the a set of views rather than to one specific view.
Hope this helps you. I've used barrier instead of guideline.
<?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/locationLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="parent">
<TextView
android:id="#+id/locationTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Save location to the song"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/locationDescription"
android:layout_width="261dp"
android:layout_height="32dp"
android:text="Your location is only requested when a new song is identified. Location details are never sent to the server"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationTitle" />
<android.support.constraint.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="locationDescription,locationTitle" />
<Switch
android:id="#+id/locationPermissionSwitch"
android:layout_width="41dp"
android:layout_height="26dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/barrier"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/viewLocationLayout"
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="#d6d6d6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationDescription" />
</android.support.constraint.ConstraintLayout>
You need to change the constraints of the switch like this
<Switch
android:id="#+id/locationPermissionSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#id/guidelineLocationLayout"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
You are constraining the bottom of the switch to the top of the parent and top of the switch to the bottom of the parent. You have to change it to layout_constraintTop_toTopOf and layout_constraintBottom_toBottomOf

Categories

Resources