Button showing up in top left - android

The button I made is in the center of the design screen, but when I run the app it is showing up in the top left.
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="231dp" />

ZeekHuge is right, here try this:
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Button"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="231dp" />

This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you add constraints.
The layout editor allows you to place widgets anywhere on the canvas, and it records the current position with designtime attributes (such as layout_editor_absoluteX.) These attributes are not applied at runtime, so if you push your layout on a device, the widgets may appear in a different location than shown in the editor. To fix this, make sure a widget has both horizontal and vertical constraints by dragging from the edge connections.
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="231dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>

I assume you're using ConstraintLayout? The problem is these attributes:
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="231dp"
tools attributes affect how a view looks in the Android Studio preview, but have no effect on how it looks when you actually run the app. You will need to add constraints to your button if you want it to be centered when you run. Add these:
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Center Btn"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"/>

Related

Put on the bottom elements in an App on Android Studio

I have an issue with my App on Android Studio.
I want to know how can I put on the bottom of my layout (in a fixed position) without ruining the structure on various smartphones. I'm using a Linear Layout and the elements to put at the bottom are :
Edit-text (comments area) + Button "Send comment" in the right of the Edit-Text. Thank you.
Ideal approach is to use a ConstraintLayout, because it will give you a lot of options to do that. Using a LinearLayout if the linear layout height is match parent. You can set the item property of gravity=bottom.
Sample Code of constraint layout
<androidx.constraintlayout.widget.ConstraintLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:background="#drawable/bg_input"
android:hint="Taper votre message"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="#drawable/bg_button"
android:text="Send"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="#+id/editText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/editText" />
</androidx.constraintlayout.widget.ConstraintLayout>
Maybe you can use a new Layout called ConstraintLayout. You have to put this new layout at the same level as your linear layout and it will not destroy your work.

How do margins in chains work in ConstraintLayout 1.1.0 (beta)

I have had a couple of my layouts blow up since changing over to ConstraintLayout version 1.1.0-beta4. Before I make any changes, I want to get a better understanding of how margins work in ConstraintLayout chains. In the following, I compare a layout in ConstraintLayout version 1.0.2 to version 1.1.0-beta4, but I believe that the issue first arose in 1.1.0-beta2.
My goal is to have some text views stretch across the screen with gaps between the 1st and 2nd text views and the 2nd and 3rd text views. The background should show in these margins. To do this, I create a horizontal chain and specify an end margin from the left text view to the center text view and an end margin from the center text view to the right text view. The horizontal chain style is spread_inside.
Example 1 - Using ConstraintLayout version 1.0.2
This is how things look in version 1.0.2 and is what I expect.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#android:color/holo_blue_light">
<TextView
android:id="#+id/tvLeft"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginEnd="8dp"
android:background="#android:color/white"
android:gravity="center"
android:text="Text1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/tvCenter"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/tvCenter"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginEnd="8dp"
android:background="#android:color/white"
android:gravity="center"
android:text="Text2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/tvRight"
app:layout_constraintStart_toEndOf="#+id/tvLeft"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/tvRight"
android:layout_width="0dp"
android:layout_height="35dp"
android:background="#android:color/white"
android:gravity="center"
android:text="Text3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/tvCenter"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</android.support.constraint.ConstraintLayout>
Example 2 - Using ConstraintLayout version 1.1.0-beta4
This same layout looks like the following in version 1.1.0-beta4 of ConstraintLayout. Notice that the margins have disappeared. I expect that this should look the same as example 1, but it doesn't.
Example 3 - Using ConstraintLayout version 1.1.0-beta4 with start margin
If I take this same layout and simply add a start margin of 8dp to the right text view (tvRight), my margins reappear not only between the center and right text views but also between the left and center textviews although I have not changed the margins there.
This is more than just the previously set margins suddenly being honored. If I set the start margin on the rightmost text view to '48dp', what appears to be a 48dp margin also appears between the left and center text views.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#android:color/holo_blue_light">
<!-- TextViews tvLeft & tvRight not shown but are the same as above.-->
<TextView
android:id="#+id/tvRight"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="48dp"
android:background="#android:color/white"
android:gravity="center"
android:text="Text3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/tvCenter"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</android.support.constraint.ConstraintLayout>
So, my question is, "Why am I seeing these results?" How are margins handled in ConstraintLayout chains, especially spread_inside chains? Has there been a change in the way chain margins are handled, or am I missing something? I am looking for an explanation or a reference to some documentation that explains all this.
I can find no documentation that gives an authoritative answer to this exact question. However, there is a little bit of discussion about margins in the API documentation for ConstraintLayout:
If side margins are set, they will be applied to the corresponding constraints (if they exist)
In the specific instance of a chain, you have two-way constraints between each view. That is, not only is View A's end constrained to View B's start, but View B's start is also constrained to View A's end.
In your posted layout, View A has an end constraint and an end margin, but View B has a start constraint with no start margin. As far as I can tell, this means you have conflicting rules in your layout (View A wants to be 8dp away from View B, but View B wants to be 0dp from View A). Perhaps different versions of the ConstraintLayout library have different strategies for (a) determining whether this even counts as a conflict and (b) resolving the conflict if so.
Via experimentation, here is how I've found margins to work in chains on different ConstraintLayout library versions:
Version 1.0.2
Side margins on each view in the chain don't depend on or affect other views in the chain. This has (at least) two visible effects on behavior. First, adding margin to one view will push the other view away by that amount, regardless of that view's margins. Second, adding margin to one view will not affect margins of views farther down the chain (e.g. putting 8dp end margin on your first view does not by itself also cause 8dp worth of space to appear between your second and third views).
Version 1.1.0-beta4
Side margins on each view in the chain both depend on and affect other views in the chain. Again, this has two visible effects on behavior. First, adding margin to one view will not push the other view away unless it also has a margin of that same amount*. Second, adding margin between the first and second view of the chain will also affect the spacing between the second and third view of the chain**.
*: It seems that 1.1.0-beta4 allows just a start margin to push the views apart, while just an end margin will have no effect. Regardless, I recommend matching the margins.
**: I suspect this is because the chain is trying to allocate "space" evenly. The margins between views A and B create a gap, and since the chain wants to enforce a consistent spacing it adds a similar gap between views B and C.
Examples:
Stripped way down, here's a layout just like your original, with the margins changed slightly. I've left every other attribute unchanged.
<android.support.constraint.ConstraintLayout>
<TextView
android:layout_marginEnd="8dp"/>
<TextView
android:layout_marginStart="8dp"/>
<TextView/>
</android.support.constraint.ConstraintLayout>
v1.0.2:
v1.1.0-beta4:
This should illustrate the two differences between the library versions. Again, I've been completely unable to find official documentation that explains all this, but it appears to be true just based on experimentation.
Expanding on Ben P.'s answer, I have determined the following regarding margins in ConstraintLayout chains. This information applies to ConstraintLayout version 1.1.0-beta4.
General Observations
Within a chain, all start margins (android:layout_marginStart) are honored. This means that the spacing between the views will not be less than the specified start margin. However, the spacing may be greater as explained below.
End margins (android:layout_marginEnd) have no relevance and seem to be ignored. This does not apply to the end margins of the view at the end of the chain but only to the interior margins where views are cross-linked to create the chain.
When a chain is centered within its constraints, the chain is centered between the start margin of the chain's head and the end margin of the chain's tail.
In the examples below, views "A","D" ang "G" are constrained to the parent start. Views "C", "F" and "I" are constrained to the parent end.
Chain Style: packed
If the chain style is "packed," all views are placed end-to-end separated by the specified start margins. The spacing between the views can vary according to how the start margins are defined. In the following image, the width of the views are match_constraints and the margins are set as indicated.
If the widths of the views are set to something other than match_constraints, the views are still packed with the specified margins but the chain is centered between the start margin of the chain's head and the end margin of the chain's tail.
I came to this interpretation instead of considering the end margin to be attached to the end view because the Android Studio designer has this same interpretation:
Chain Style: spread
In the "spread" chain style, all views are distributed between the start and end constraints such that the space before and after each view is the same and equal to the greatest start margin defined. If the width of each view is match_constraints, then all the views will have the same width by default.
Chain Style: spread_inside
The spread_inside style of chains will take the first view of the chain and anchor it to its start constraint while honoring its start margin. The end view will be anchored to its end constraint while honoring its end margin. Interior views will be distributed with equal spacing between the views like spread chains.
Below is the same layout with various margins set. Views "F" and "I" have a start margin of 8dp set but the gap has expanded to 16dp. View "G", "H" and "I" are all of equal width although they don't appear to be.
The XML for this layout is presented at the end of this post.
Of interest but of no real importance: The different chain types are indistinguishable if the views have a width of match_constraints and all margins are zero.
The information above also applies to vertical chains. Substitute android:layout_marginTop for android:layout_marginStart and android:layout_marginBottom for android:layout_marginEnd.
Layout
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light">
<TextView
android:id="#+id/heading1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="packed, match_constraints"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/textA"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginTop="8dp"
android:background="#android:color/white"
android:gravity="center"
android:text="A"
android:textColor="#android:color/black"
app:layout_constraintEnd_toStartOf="#+id/textB"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/heading1"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
app:layout_constraintEnd_toStartOf="#id/textB"
app:layout_constraintTop_toTopOf="#id/textB" />
<TextView
android:id="#+id/textB"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:background="#android:color/darker_gray"
android:gravity="center"
android:text="B"
android:textColor="#android:color/white"
app:layout_constraintEnd_toStartOf="#+id/textC"
app:layout_constraintStart_toEndOf="#+id/textA"
app:layout_constraintTop_toTopOf="#+id/textA"
tools:ignore="HardcodedText" />
<View
android:id="#+id/view16dpOnC"
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#fffb00"
app:layout_constraintEnd_toStartOf="#id/textC"
app:layout_constraintTop_toTopOf="#+id/textC" />
<TextView
android:id="#+id/textC"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="16dp"
android:background="#android:color/white"
android:gravity="center"
android:text="C"
android:textColor="#android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textB"
app:layout_constraintTop_toTopOf="#+id/textA"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/heading2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="spread, match_constraints"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/textA"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#00ff19"
app:layout_constraintEnd_toStartOf="#id/textD"
app:layout_constraintTop_toTopOf="#id/textD" />
<TextView
android:id="#+id/textD"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginTop="8dp"
android:background="#android:color/white"
android:gravity="center"
android:text="D"
android:textColor="#android:color/black"
app:layout_constraintEnd_toStartOf="#+id/textE"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/heading2"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#fffb00"
app:layout_constraintEnd_toStartOf="#id/textE"
app:layout_constraintTop_toTopOf="#id/textE" />
<TextView
android:id="#+id/textE"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="16dp"
android:background="#android:color/darker_gray"
android:gravity="center"
android:text="E"
android:textColor="#android:color/white"
app:layout_constraintEnd_toStartOf="#+id/textF"
app:layout_constraintStart_toEndOf="#+id/textD"
app:layout_constraintTop_toTopOf="#+id/textD"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#003cff"
app:layout_constraintStart_toEndOf="#id/textE"
app:layout_constraintTop_toTopOf="#+id/textE" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
app:layout_constraintEnd_toStartOf="#id/textF"
app:layout_constraintTop_toTopOf="#id/textF" />
<TextView
android:id="#+id/textF"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:background="#android:color/white"
android:gravity="center"
android:text="F"
android:textColor="#android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textE"
app:layout_constraintTop_toTopOf="#+id/textD"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#00ff19"
app:layout_constraintStart_toEndOf="#id/textF"
app:layout_constraintTop_toTopOf="#id/textF" />
<TextView
android:id="#+id/heading3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="spread_inside, match_constraints"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/textD"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#003cff"
app:layout_constraintEnd_toStartOf="#id/textG"
app:layout_constraintTop_toTopOf="#+id/textG" />
<TextView
android:id="#+id/textG"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="#android:color/white"
android:gravity="center"
android:text="G"
android:textColor="#android:color/black"
app:layout_constraintEnd_toStartOf="#+id/textH"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/heading3"
tools:ignore="HardcodedText" />
<View
android:layout_width="16dp"
android:layout_height="35dp"
android:background="#fffb00"
app:layout_constraintEnd_toStartOf="#id/textH"
app:layout_constraintTop_toTopOf="#id/textH" />
<TextView
android:id="#+id/textH"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="16dp"
android:background="#android:color/darker_gray"
android:gravity="center"
android:text="H"
android:textColor="#android:color/white"
app:layout_constraintEnd_toStartOf="#+id/textI"
app:layout_constraintStart_toEndOf="#+id/textG"
app:layout_constraintTop_toTopOf="#+id/textG"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#003cff"
app:layout_constraintStart_toEndOf="#id/textH"
app:layout_constraintTop_toTopOf="#id/textH" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
app:layout_constraintEnd_toStartOf="#id/textI"
app:layout_constraintTop_toTopOf="#id/textI" />
<TextView
android:id="#+id/textI"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:background="#android:color/white"
android:gravity="center"
android:text="I"
android:textColor="#android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/textH"
app:layout_constraintTop_toTopOf="#+id/textG"
tools:ignore="HardcodedText" />
<View
android:layout_width="8dp"
android:layout_height="35dp"
android:background="#ff00cc"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="#id/textC"
app:layout_constraintTop_toTopOf="#id/textC" />
<View
android:id="#+id/view8dp"
android:layout_width="8dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:background="#ff00cc"
app:layout_constraintBottom_toTopOf="#id/view8dpGap"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textG"
app:layout_constraintVertical_bias="0.100000024"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/text8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="8dp start margin"
app:layout_constraintBottom_toBottomOf="#+id/view8dp"
app:layout_constraintStart_toEndOf="#id/view8dp"
app:layout_constraintTop_toTopOf="#+id/view8dp"
tools:ignore="HardcodedText" />
<View
android:id="#+id/view8dpGap"
android:layout_width="8dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:background="#003cff"
app:layout_constraintBottom_toTopOf="#+id/view16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view8dp" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="8dp gap not defined by start margin"
app:layout_constraintBottom_toBottomOf="#+id/view8dpGap"
app:layout_constraintStart_toEndOf="#+id/view8dpGap"
app:layout_constraintTop_toTopOf="#+id/view8dpGap"
tools:ignore="HardcodedText" />
<View
android:id="#+id/view16dp"
android:layout_width="17dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:background="#fffb00"
app:layout_constraintBottom_toTopOf="#+id/view16dpGap"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view8dpGap" />
<TextView
android:id="#+id/text16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="16dp start margin"
app:layout_constraintBottom_toBottomOf="#+id/view16dp"
app:layout_constraintStart_toEndOf="#+id/view16dp"
app:layout_constraintTop_toTopOf="#+id/view16dp"
tools:ignore="HardcodedText" />
<View
android:id="#+id/view16dpGap"
android:layout_width="17dp"
android:layout_height="35dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:background="#00ff19"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view16dp" />
<TextView
android:id="#+id/text16dpGap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="16dp gap not defined by start margin"
app:layout_constraintBottom_toBottomOf="#+id/view16dpGap"
app:layout_constraintStart_toEndOf="#+id/view16dpGap"
app:layout_constraintTop_toTopOf="#+id/view16dpGap"
tools:ignore="HardcodedText" />
</android.support.constraint.ConstraintLayout>

ConstraintLayout drawing order/layer order

Simple question:
What is the exact algorithm used by ConstraintLayout in order to know which View is drawn first and which View is drawn last?
In RelativeLayout, the last View in the XML file is drawn last, hence it will be on top of everything, obscuring the Views which where drawn earlier.
Why does not ConstraintLayout carry the same function (at least, apparently)?
The following code results in the Button being displayed on top of the included View.
<Button
android:id="#+id/calculate"
android:layout_width="183dp"
android:layout_height="76dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:text="C A L C U L A T E"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<include
android:id="#+id/help_window"
layout="#layout/help_window"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/include4" />
</android.support.constraint.ConstraintLayout>
Alright. I solved this now.
Apparently buttons are treated seperately. With a buildt in elevation to alwyas be on top.
solution is to remove this elevation, write this in the xml file in your button:
android:stateListAnimator="#null"

ConstraintLayout View.GONE usage

I recently started using ConstraintLayout. As I discovered, most of the features are pretty straight forward, and well explained in the docs with samples, text and video tutorials and all.
The thing that got in my mind is how to I solve this 'puzzle' as elegant as possible?
As you can see, in the right section of the layout, I have multiple Views aligned left. On the last but one row, there are 3 Views aligned horizontally (they are also aligned TOP between each other).
Problem is: if I set first View's visibility from that row as GONE, the other two (in the same row), go left as expected, but the one underneath (last row in the vertical alignment) goes over the row before (because its constraintTop property is set as bottom of the View set as GONE).
The only solution I can think of is using a ViewGroup to group those 3 Views and add the constraint to last row View to it.
Am I missing some property on ConstraintLayout which could help my case? Maybe some sort of fallback (or multiple) constraints if one of them is set on a GONE View?
Sorry if my explanation seem quite abstruse, maybe the pictures will help you more :)
LE: Added layout: https://gist.github.com/DoruAdryan/7e7920a783f07b865489b1af0d933570
You can use the new Barriers feature of ConstraintLayout.
<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="wrap_content">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/iv_item_small_product_image"
android:layout_width="113dp"
android:layout_height="113dp"
android:layout_marginLeft="7dp"
android:layout_marginStart="7dp"
android:background="#android:drawable/btn_radio"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.AppCompatImageView
android:id="#+id/iv_row_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:background="#android:drawable/bottom_bar"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ro.emag.android.views.FontTextView
android:id="#+id/tv_row_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:maxLines="2"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/iv_row_1"
app:layout_goneMarginTop="0dp"
tools:text="Some text long enough to be split on multiple lines on some devices." />
<android.support.v7.widget.AppCompatRatingBar
android:id="#+id/rb_row_3_1"
style="#style/Widget.AppCompat.RatingBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="9dp"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.1"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintTop_toBottomOf="#id/tv_row_2" />
<TextView
android:id="#+id/tv_row_3_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:layout_marginTop="9dp"
app:layout_constraintLeft_toRightOf="#+id/rb_row_3_1"
app:layout_constraintTop_toBottomOf="#id/tv_row_2"
tools:text="106" />
<TextView
android:id="#+id/tv_row_3_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:layout_marginTop="9dp"
app:layout_constraintLeft_toRightOf="#+id/tv_row_3_2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_row_2"
app:layout_goneMarginLeft="0dp"
app:layout_goneMarginStart="0dp"
tools:text="Options available" />
<android.support.constraint.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="rb_row_3_1, tv_row_3_2, tv_row_3_3" />
<TextView
android:id="#+id/tv_row_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/barrier"
tools:text="Some text on last row" />
</android.support.constraint.ConstraintLayout>
Now, the last row is depending on the barrier instead of one of the views of the third row. As the barrier is depending on the three views of the second row, you won't have the gone margin problem.
Plus, i noticed that you don't need the guideline. The right segment can depend on the imageview directly.
In case you are not familiar with Barriers, here's a link to help you out.
As this feature is available only in the 1.1.0 beta1 release of ConstraintLayout, don't forget to add this line to your build.gradle file.
compile 'com.android.support.constraint:constraint-layout:1.1.0-beta1'
make sure to include maven { url "https://maven.google.com" }

Evenly spacing views using ConstraintLayout

A common use for LinearLayout is to evenly space (weight) views, for example:
How do you implement evenly spaced views like this using the new ConstraintLayout?
ConstraintLayout links for reference: blog post, I/O session video
There are two ways to accomplish this using ConstraintLayout: Chains and Guidelines. To use Chains, make sure you are using ConstraintLayout Beta 3 or newer and if you want to use the visual layout editor in Android Studio, make sure you are using Android Studio 2.3 Beta 1 or newer.
Method 1 - Using Chains
Open the layout editor and add your widgets as normal, adding parent constraints as needed. In this case, I have added two buttons with constraints to the bottom of the parent and side of the parent (left side for Save button and right side for Share button):
Note that in this state, if I flip to landscape view, the views do not fill the parent but are anchored to the corners:
Highlight both views, either by Ctrl/Cmd clicking or by dragging a box around the views:
Then right-click on the views and choose "Center Horizontally":
This sets up a bi-directional connection between the views (which is how a Chain is defined). By default the chain style is "spread", which is applied even when no XML attribute is included. Sticking with this chain style but setting the width of our views to 0dp lets the views fill the available space, spreading evenly across the parent:
This is more noticeable in landscape view:
If you prefer to skip the layout editor, the resulting XML will look like:
<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_save"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/button_save_text"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="#+id/button_share"
app:layout_constraintHorizontal_chainStyle="spread" />
<Button
android:id="#+id/button_share"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/button_share_text"
android:layout_marginStart="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintLeft_toRightOf="#+id/button_save"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
Details:
setting the width of each item to 0dp or MATCH_CONSTRAINT lets the views fill the parent (optional)
the views must be linked together bidirectionally (right of save button links to share button, left of share button links to save button), this will happen automatically via the layout editor when choosing "Center Horizontally"
the first view in the chain can specify the chain style via layout_constraintHorizontal_chainStyle, see the documentation for various chain styles, if the chain style is omitted, the default is "spread"
the weighting of the chain can be adjusted via layout_constraintHorizontal_weight
this example is for a horizontal chain, there are corresponding attributes for vertical chains
Method 2 - Using a Guideline
Open your layout in the editor and click the guideline button:
Then select "Add Vertical Guideline":
A new guideline will appear, that by default, will likely be anchored to the left in relative values (denoted by left-facing arrow):
Click the left-facing arrow to switch it to a percentage value, then drag the guideline to the 50% mark:
The guideline can now be used as an anchor for other views. In my example, I attached the right of the save button and the left of the share button to the guideline:
If you want the views to fill up the available space then the constraint should be set to "Any Size" (the squiggly lines running horizontally):
(This is the same as setting the layout_width to 0dp).
A guideline can also be created in XML quite easily rather than using the layout editor:
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/guideline"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
To create 2 views in same line, equal width, just need to define
<android.support.constraint.ConstraintLayout
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:text="Button 1"
app:layout_constraintEnd_toStartOf="#+id/button2"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/button1" />
</android.support.constraint.ConstraintLayout>
Note
width = 0dp (MATCH_CONSTRAINT)
Constraint of button1 and button2 must like above
Result
MORE
If you want View1 bigger than View2 you can use weight or percent.
Example, View1 width = 2 *View2 width use weight
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="#+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toStartOf="#+id/button4"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
/>
<Button
android:id="#+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#+id/button3"
/>
</android.support.constraint.ConstraintLayout>
Result
Example, View1 width = 2 *View2 width use percent
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="#+id/button5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 5"
app:layout_constraintEnd_toStartOf="#+id/button6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.667"
/>
<Button
android:id="#+id/button6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/button5"
app:layout_constraintWidth_percent="0.333"
/>
</android.support.constraint.ConstraintLayout>
Result
Well if it helps someone
the key is here app:layout_constraintHorizontal_weight="1" and
the best thing about constraint layout is that it supports circular dependency and here this is what I have done using exactly that.
For first child
app:layout_constraintEnd_toStartOf="#+id/textInputSecondChild"
For second child
app:layout_constraintLeft_toRightOf="#+id/textInputFirstChild"
here is the complete demo
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputParent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<EditText
android:id="#+id/editTextParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/state" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputFirstChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="#+id/textInputSecondChild"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textInputParent">
<EditText
android:id="#+id/editTextChildOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/pin_code" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputSecondChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="#+id/textInputFirstChild"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textInputParent">
<EditText
android:id="#+id/editTextChildSecond"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/country" />
</android.support.design.widget.TextInputLayout>
You shoul read about weighted chains. An example of code is here.
<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="wrap_content"
>
<TextView
android:id="#+id/figure_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="#id/figure_2"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
tools:text="1"
/>
<TextView
android:id="#+id/figure_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="#id/figure_3"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/figure_1"
tools:text="2"
/>
<TextView
android:id="#+id/figure_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="#id/figure_4"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/figure_2"
tools:text="3"
/>
<TextView
android:id="#+id/figure_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/figure_3"
tools:text="4"
/>
</android.support.constraint.ConstraintLayout>
So, set android:layout_width="0dp", app:layout_constraintHorizontal_weight="1" and link every view with neighbours like:
app:layout_constraintStart_toEndOf="#id/figure_2"
app:layout_constraintEnd_toStartOf="#id/figure_4"
Once you have your chained items, you can still use weights on them like relative layout to keep them evenly spaced. The example below shows how to keep them evenly spaced with different size textViews.
<TextView1
app:layout_constraintHorizontal_weight="1" />
<TextView2
app:layout_constraintHorizontal_weight="1" />
<TextView3
app:layout_constraintHorizontal_weight="1" />
<TextView4
app:layout_constraintHorizontal_weight="1" />

Categories

Resources