The app:layout_constraintVertical_chainStyle="spread_inside" or any of the options - packed, spread - has not effect; why? - android

<?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"
app:layout_constraintVertical_chainStyle="spread_inside">
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="#+id/button2"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/button1"
app:layout_constraintBottom_toTopOf="#id/button3"/>
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/button2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
In the provided code, the attribute app:layout_constraintVertical_chainStyle="spread_inside" is set on the parent ConstraintLayout. This attribute controls the spacing behavior between views in a vertical chain.
According to the documentation, the "spread_inside" chain style should evenly distribute the extra space between views in the chain, while aligning the first and last views to the top and bottom of the chain, respectively.
However, when the layout is rendered, the chain style does not appear to have any effect. This could be due to other constraints that are conflicting with the chain style; what can I do to make it to work?.

According to the documentation: Chains are controlled by attributes set on the first element of the chain, so instead of applying the attribute to the ConstraintLayout, apply it to the top most widget inside the chain:
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="#+id/button2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread_inside" />

Related

Buttons do not evenly occupy parent width using constraint layout chains

I am trying to create a chain with 2 buttons at the bottom of a ConstraintLayout using a chain but it is not working. I have removed a couple of views above the buttons for clarity
<?xml version="1.0" encoding="utf-8"?>
<ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginEnd="10dp"
android:text="Button 1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/button2"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintTop_toBottomOf="#id/guideline" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginStart="4dp"
android:layout_marginEnd="10dp"
android:text="Button 2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/button1"
app:layout_constraintTop_toBottomOf="#id/guideline" />
</ConstraintLayout>
The buttons do show up at the bottom of the screen, one next to each other but they don't occupy the parent width i.e. each being 50% of the screen. They are wrapping around the text at the side of the screen.
What am I doing wrong?
Update:
I see that if I add something other than 0dp e.g. 200dp it expands the views. But I was under the impression that I should be using 0dp to respect the constraints
Here is an example of implementation spreading two button at the bottom of their parents 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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:text="Button 1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/button2"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:text="Button 2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/button1" />
</androidx.constraintlayout.widget.ConstraintLayout>
What's the difference between this and your version. For button1 there is additional rule which indicated where is the start of the button: app:layout_constraintStart_toStartOf="parent" and accordingly for button2 where is the end: app:layout_constraintEnd_toEndOf="parent". Which actually helps the ContraintLayout properly layout the buttons.
Btw, you don't need to add android:layout_alignParentBottom="true" to your buttons since the parent is not a RelativeLayout.

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"/>

Why are the XML Elements not visible on my emulator in android studio?

My problem is that the controls (checkboxes, buttons etc) which I have placed are not visible on my emulator.
Below is my XML file:
<?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"
tools:context=".MainActivity">
<Button
android:id="#+id/btn1"
android:layout_width="match_parent"
android:layout_height="52dp"
android:text="#string/btn1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteY="0dp" />
<Button
android:id="#+id/btn2"
android:layout_width="match_parent"
android:layout_height="77dp"
android:text="#string/btn2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteY="68dp" />
<fragment
android:id="#+id/fragment"
android:name="com.example.mypc.fragmentactivity.Fragment1"
android:layout_width="222dp"
android:layout_height="285dp"
android:layout_marginBottom="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
Here is my XML (design view):
Here is my emulator window:
Is there is something wrong in my XML file?
Please provide me solution for this.
How should I handle this?
You are using ConstraintLayout without relative positioning.
According to developer site:
Relative positioning is one of the basic building blocks of creating layouts in ConstraintLayout. Those constraints allow you to position a given widget relative to other. You can constrain a widget on the horizontal and vertical axis:
Horizontal Axis: left, right, start and end sides
Vertical Axis: top, bottom sides, and text baseline
Here is the solution which may help you:
<?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"
tools:context=".MainActivity">
<Button
android:id="#+id/btn1"
android:layout_width="match_parent"
android:layout_height="52dp"
android:text="#string/btn1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="#id/btn2"/>
<Button
android:id="#+id/btn2"
android:layout_width="match_parent"
android:layout_height="77dp"
android:text="#string/btn2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/btn1"
android:layout_marginTop="10dp"/>
</android.support.constraint.ConstraintLayout>
I have used relative positioning to solve the problem. If you are using constraint layout then without relative positioning your views will get overlap with each other.
Because you didn't align properly the second button. it seems like second button overlap first one.
try this one
<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=".activites.HomeActivity"
android:layout_margin="6dp">
<Button
android:id="#+id/btnOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Button One"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btnTwo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Button Two"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnOne" />
<fragment
android:id="#+id/fragment"
android:layout_width="222dp"
android:layout_height="285dp"
android:layout_marginBottom="40dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnTwo"
tools:ignore="MissingConstraints" />
</android.support.constraint.ConstraintLayout>
output would be like this
In your code your elements are overflowing each other at one position that is why they are not visible.
My suggestion is do not constraint Layout at initial stage of learning android.
Use Linear Layout in place of constraint Layout.
Since in constraint Layout Layout Editor uses constraints to determine the position of a UI element within the layout. You have to give many constraint XML attributes like.
app:layout_editor_absoluteX="73dp"
app:layout_editor_absoluteY="176dp"
app:layout_constraintLeft_creator="1"
app:layout_constraintTop_creator="1"
app:layout_constraintRight_creator="1"
to specify the position of elements in layout.
Use Linear Layout in place of Constraint Layout and give
orientation:"vetical"
to view all your elements.
The layout_editor attributes are only used for the editor preview and have no effect on the final layouts. You should position your elements using the ConstraintLayout specific attributes.
It's used to just for preview purpose.
tools:layout_editor_absoluteY="68dp"
Simply use LinearLayout instead of ConstraintLayout. Also provide orientation vertical to that LinearLayout.
It will helps you
<?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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="#+id/btn1"
android:layout_width="match_parent"
android:layout_height="52dp"
android:text="#string/btn1" />
<Button
android:id="#+id/btn2"
android:layout_width="match_parent"
android:layout_height="77dp"
android:text="#string/btn2" />
<fragment
android:id="#+id/fragment"
android:name="com.example.mypc.fragmentactivity.Fragment1"
android:layout_width="222dp"
android:layout_height="285dp"
android:layout_marginBottom="40dp" />
</LinearLayout>

How can I push all but one view in a vertical chain to the top, and the last view to the bottom?

I have a set of three buttons in a vertical chain in a ConstraintLayout:
<?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">
<Button
android:id="#+id/button_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintBottom_toTopOf="#+id/button_2"
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.0"
app:layout_constraintVertical_chainStyle="packed" />
<Button
android:id="#+id/button_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintBottom_toTopOf="#+id/button_3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button_1" />
<Button
android:id="#+id/button_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button_2" />
</android.support.constraint.ConstraintLayout>
This looks like this:
How can I use features of the ConstraintLayout to make it appear like this, while still preserving the chain?
I have tried using the various bias settings, but they only take effect under the packed chain mode, and then only on the whole chain. Is it possible to individually bias the positions of the views within a chain?
An idea to achieve this is to add a Space helper view as a part of the chain that will take up all the remaining unused space as necessary. Example XML:
<?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">
<Button
android:id="#+id/button_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintBottom_toTopOf="#+id/button_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="packed" />
<Button
android:id="#+id/button_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintBottom_toTopOf="#+id/space"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button_1" />
<android.support.v4.widget.Space
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/button_3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/button_2" />
<Button
android:id="#+id/button_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/space" />
</android.support.constraint.ConstraintLayout>
Here is your need, You should remove below from button_3
app:layout_constraintTop_toBottomOf="#+id/button_2"
and have to add below
app:layout_constraintStart_toStartOf="parent"
Set the chain with a style of packed with a vertical bias of 0. That will place the three views at the top. To move the bottom view to the bottom of the screen, you will need to set a top margin on the bottom view. Since the margin will vary by device and orientation, you will need to set it programmatically.
Unfortunately, if the middle view can expand vertically as with a multi-line EditText that you mention, then setting the margin will still work, but you will need to make adjustments as the middle view expands. This is all doable but a little involved.

Align a group of views containing a chain in a ConstraintLayout

I have three views in a ConstraintLayout and want to align then like this:
Right now views B and C form a vertical chain, and A is centered relative to the chain. But how do I align the entire group centered in the parent? Note that View C may be GONE.
Here is a visual answer without nesting layouts.
Steps
Chain and pack B and C vertically
Chain and pack A and C horizontally
Align B and C horizontal centers
Center A vertically
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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/textView"
android:layout_width="69dp"
android:layout_height="67dp"
android:background="#fb0000"
android:gravity="center"
android:text="A"
android:textColor="#000000"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/textView3"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="154dp"
android:layout_height="73dp"
android:background="#2000ff"
android:gravity="center"
android:text="B"
android:textColor="#ffffff"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="#+id/textView3"
app:layout_constraintStart_toStartOf="#+id/textView3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/textView3"
android:layout_width="187dp"
android:layout_height="61dp"
android:background="#f1a500"
android:gravity="center"
android:text="C"
android:textColor="#000000"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/textView"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
</android.support.constraint.ConstraintLayout>
Personal opinion
Switch to Flutter. The layout is much easier than ConstraintLayout.
The easiest and most understandable way to center the group is to make it a group by nesting the views within a ConstraintLayout that, itself, is nested in a ConstraintLayout as follows:
<android.support.constraint.ConstraintLayout
android:id="#+id/outerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/innerLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
[A, B, and C views here...]
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
The outer layout could be another type of ViewGroup such as LinearLayout using gravity.
Other solutions are possible such as a creative use of chains, barriers or guidelines, but the simplicity of the outlined solution is the most attractive in my opinion.

Categories

Resources