Convert LinearLayout to ConstraintLayout issue - android

I am trying to convert a horizontal LinearLayout that has 4 buttons of the same size to a ConstraintLayout.
The problem is that when I set one or more buttons to android:visibility="gone" in the LinearLayout the remaining buttons are resized to take the entire space (all will be the same size) and in the ConstraintLayout the buttons are removed, but still take the space.
EDIT: According to the app state, different buttons will be visible.
What do I need to change so the ConstraintLayout will behave like the LinearLayout?
EDIT: I found a mistake in the ConstraintLayout (constraint references) so I updated it and the images (the problem still exists).
LinearLayout xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="#+id/b1"
android:text="B1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
/>
<Button
android:id="#+id/b2"
android:text="B2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
android:visibility="gone"
/>
<Button
android:id="#+id/b3"
android:text="B3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
/>
<Button
android:id="#+id/b4"
android:text="B4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
/>
</LinearLayout>
EDIT: ConstraintLayout 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/b1"
android:text="B1"
android:layout_width="0px"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/b2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_weight="1"
/>
<Button
android:id="#+id/b2"
android:text="B2"
android:layout_width="0px"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintLeft_toRightOf="#+id/b1"
app:layout_constraintRight_toLeftOf="#+id/b3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_weight="1"
/>
<Button
android:id="#+id/b3"
android:text="B3"
android:layout_width="0px"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="#+id/b2"
app:layout_constraintRight_toLeftOf="#+id/b4"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_weight="1"
android:layout_marginTop="0dp"/>
<Button
android:id="#+id/b4"
android:text="B4"
android:layout_width="0px"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="#+id/b3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_weight="1"
/>
</android.support.constraint.ConstraintLayout>

You can easily convert any layout to a ConstraintLayout, just follow these directions:
Go to the design tab inside the layout editor of Android Studio
Open the Component Tree
Right click the LinearLayout (or other layout) you want to convert
Click on "Convert LinearLayout to ConstraintLayout"

You can probably change your layout to something like:
<?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:orientation="horizontal">
<Button
android:id="#+id/b1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="B1"
app:layout_constraintBaseline_toBaselineOf="#+id/b3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/b3"
tools:layout_constraintBaseline_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1" />
<Button
android:id="#+id/b2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="B2"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />
<Button
android:id="#+id/b3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="128dp"
android:layout_marginLeft="128dp"
android:layout_marginRight="128dp"
android:layout_marginStart="128dp"
android:text="B3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />
<Button
android:id="#+id/b4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="B4"
app:layout_constraintBaseline_toBaselineOf="#+id/b3"
app:layout_constraintLeft_toRightOf="#+id/b3"
app:layout_constraintRight_toRightOf="parent"
tools:layout_constraintBaseline_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1" />
</android.support.constraint.ConstraintLayout>
If you are having a tough time switching an existing layout to ConstraintLayout, you can go ahead and try out Android Studio's internal design tools to help you with it. You can switch to Design tab and open up Component Tree window, right click on the element you want to convert and select Convert to ConstraintLayout.

As per this android documentation, You can use Weighted Chains for this functionality.
For anyone still looking for a solution, I guess.

Related

Convert children to proper way in parent constraint layout Android

Hey I am working in android Constraint layout. In my xml I used constraint layout with linear layout. I want to know is there in any way, I can use only constraint layout remove other children layout like linear layout.
item_layout.xml
<?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="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:orientation="vertical">
<LinearLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#drawable/item_selector_background"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
tools:text="25mg" />
<TextView
android:id="#+id/subtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="8dp"
tools:text="from $1.65" />
</LinearLayout>
<LinearLayout
android:id="#+id/tagContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/item_tag_background"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:visibility="visible">
<TextView
android:id="#+id/tagText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="10dp"
android:paddingEnd="10dp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
My view look like this
I only want to achieve this through constraint layout.
There is definitely a way to do it. Something like this may work for you:
<ConstraintLayout>
<TextView
android:id="#+id/text
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="25mg" />
<TextView
android:id="#+id/subtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="8dp"
app:layout_constraintTop_toBottomOf="#id/text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="#id/tagText"
tools:text="from $1.65" />
<TextView
android:id="#+id/tagText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="10dp"
android:paddingEnd="10dp"
app:layout_constraintTop_toBottomOf="#id/subtext"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</ConstraintLayout>
Just pull the child layouts out and constrain the views the way that you want them.
Note: This is not exact. You may have to play with the constraints to get them the way you want it.
You can use View behind them to set background for the first two TextViews like,
<ConstraintLayout
...>
<View
android:id="#+id/backgroundView"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#drawable/item_selector_background"
app:layout_constraintTop_toTopOf="#id/text"
app:layout_constraintEnd_toEndOf="#id/subtext"
app:layout_constraintStart_toStartOf="#id/subtext"
app:layout_constraintBottom_toBottomOf="#id/subtext"/>
<TextView
android:id="#+id/text"
...
/>
<TextView
android:id="#+id/subtext"
...
/>
<TextView
android:id="#+id/tagText"
...
/>
...
</ConstraintLayout>
the height and width of the backgroundView can be constrained to match the first two TextViews

ConstraintLayout: How to center a text between two buttons of varying sizes

I'm making a dialog with a header that contains a "Cancel" button, a title and finally a "Save" button. See image. The title is constrained between the buttons. However, when one of the buttons are longer than the other the title moves to one side as it is told to stay in the middle between the buttons.
How can I make the title view be centered below the drag handle and at the same time let it expand all the way to the buttons without overlapping them?
Thanks!
I just implement the same functionality on three buttons that align horizontal and don't overlap each other.
Please create views in the same way below implementation.
<Button
android:id="#+id/btnExit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/dp_1"
android:background="#drawable/bluebtn_gradient_rectangle"
android:text="#string/exit"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btnMemoryPreview"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvFill" />
<Button
android:id="#+id/btnMemoryPreview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/dp_1"
android:background="#drawable/bluebtn_gradient_rectangle"
android:text="#string/user_memory_preview"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/UserMemoryWrite"
app:layout_constraintStart_toEndOf="#+id/btnExit"
app:layout_constraintTop_toBottomOf="#+id/tvFill" />
<Button
android:id="#+id/UserMemoryWrite"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/dp_1"
android:background="#drawable/bluebtn_gradient_rectangle"
android:text="#string/rfid_write"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/btnMemoryPreview"
app:layout_constraintTop_toBottomOf="#+id/tvFill" />
this is the only hack where you can set title without overlapping in centre of the screen
make one temp button same as long button in invisible mode
<?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/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="long cancel"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="long cancel"
android:visibility="invisible"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/black"
android:gravity="center"
android:padding="#dimen/_10sdp"
android:text="title"
android:textColor="#color/white"
app:layout_constraintLeft_toRightOf="#id/btn1"
app:layout_constraintRight_toLeftOf="#id/btn3"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
EDIT
this is another way, but this will be a mess when you have a very large title
<?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/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="long cancel"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/txt"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save"
app:layout_constraintLeft_toRightOf="#id/txt"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/black"
android:gravity="center"
android:padding="#dimen/_10sdp"
android:text="title dfgfd gdg dfgdfg dfgdfg fdgfdfgd fgddf dfgdgdfgdfg dfg dfgfdg df"
android:textColor="#color/white"
app:layout_constraintLeft_toRightOf="#id/guideline"
app:layout_constraintRight_toRightOf="#id/guideline"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
Edit
if you know max length of long cancel button you can set app:layout_constraintWidth_percent to TextView based on that button width
<TextView
android:id="#+id/txt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/black"
android:gravity="center"
android:padding="#dimen/_10sdp"
android:text="title dfgfd gdg dfgdfg dfgdfg fdgfdfgd fgddf dfgdgdfgdfg dfg dfgfdg df"
android:textColor="#color/white"
app:layout_constraintLeft_toRightOf="#id/guideline"
app:layout_constraintRight_toLeftOf="#id/guideline"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.4" />
Ok, so inspired by some of your answers I started looking at guidelines. The idea was to use two guidelines, one on each side of the view, and set the distance from the parent to the guideline as the width of the biggest button plus any margin. Final code looks like this:
val biggestWidth = if (cancelButton.width > saveButton.width) {
cancelButton.width + cancelButton.marginStart
} else {
saveButton.width + saveButton.marginEnd
}
guidelineRight.setGuidelineEnd(biggestWidth)
guidelineLeft.setGuidelineBegin(biggestWidth)
The title is centered between the two guidelines.
Note that this width calculation must happen after the view has been laid out. Use view.doOnLayout { } and call your calculation from there.
Your drag handle seems to be at the center of the layout. So you can relate the title to left and right of the parent instead buttons. But still overlapping could be possible if title and cancel button text is lengthy.
You can center the title with respect to the drag handle but then cannot expand the TextView between cancel and save button. I think both cannot be done simultaneoulsy.
You can use the below code to center the title w.r.t the drag handle
<?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">
<View
android:id="#+id/view"
android:layout_width="#dimen/dp_80"
android:layout_height="#dimen/dp_8"
android:layout_marginTop="#dimen/dp_8"
android:background="#color/divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dp_8"
android:text="title"
android:textSize="#dimen/sp_24"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="#id/view"
app:layout_constraintStart_toStartOf="#id/view"
app:layout_constraintTop_toBottomOf="#id/view" />
<Button
android:id="#+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="cancel"
android:textSize="#dimen/sp_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/title"
app:layout_constraintTop_toBottomOf="#id/view" />
<Button
android:id="#+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save"
android:textSize="#dimen/sp_16"
app:layout_constraintStart_toEndOf="#id/title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/view" />
</androidx.constraintlayout.widget.ConstraintLayout>
TextView
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
Cancel button
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/your_text_view_id"
Save button
app:layout_constraintStart_toEndOf="#id/your_text_view_id"
app:layout_constraintEnd_toEndOf="parent"
That way your buttons can expand freely without overlapping the text at the centre.
Remove Constrainsts button to textView and set TextView Constraints to left and right of 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/button"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="ButtonButtonButtonButtonButtonButtonButtonButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="wTextViewTextViewTextViewTextViewTextViewTextViewTextVwTextViewTextView
TextViewTextViewTextViewTextViewTextVwTextViewTextViewTextViewTextViewTextViewTextView
TextVwTextViewTextViewTextViewTextViewTextViewTextViewTextVTextViewTextViewTextViewTextView
TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView
TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button2"
app:layout_constraintStart_toEndOf="#+id/button"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Without fixed button size
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_weight="1"
android:text="ButtonButtonButtonButtonButtonButtonButtonButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="wTextViewTextViewTextViewTextViewTextViewTextViewTextVwTextViewTextView
TextViewTextViewTextViewTextViewTextVwTextViewTextViewTextViewTextViewTextViewTextView
TextVwTextViewTextViewTextViewTextViewTextViewTextViewTextVTextViewTextViewTextViewTextView
TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView
TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button2"
app:layout_constraintStart_toEndOf="#+id/button"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Issues with XML Layout and Software Buttons

So basically I have an activity with 4 buttons that in Android Studio look out of the way of the software buttons at the bottom of the screen but when I run it on my phone they are not. I'm not sure if I have the right constraints on the bottom button or not?
<?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=".NewMainMenu"
tools:layout_editor_absoluteY="25dp">
<Button
android:id="#+id/button"
android:layout_width="411dp"
android:layout_height="100dp"
android:layout_marginTop="258dp"
android:background="#android:color/holo_blue_light"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button4"
android:layout_width="411dp"
android:layout_height="100dp"
android:background="#android:color/holo_red_light"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button" />
<Button
android:id="#+id/button3"
android:layout_width="411dp"
android:layout_height="100dp"
android:background="#android:color/holo_green_light"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button4" />
<Button
android:id="#+id/button2"
android:layout_width="411dp"
android:layout_height="100dp"
android:background="#android:color/holo_orange_light"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button3" />
</android.support.constraint.ConstraintLayout>
if you use from ConstraintLayout, you can add this attribute:
app:layout_constraintBottom_toBottomOf="parent"
by this code, your view sticks on bottom of layout.
and for other views you can use from this code:
app:layout_constraintBottom_toBottomOf="#+id/{bottom View}"
The problem is that you are explicitly setting the button heights and the top button's top margin to fixed values. On your device, the total sum of all the heights and the padding exceed the height of the device.
An easy fix is to not constrain the top of the topmost button to the parent and remove the top margin. Then it will lay above the button below it but won't push down from the top of the parent.
Generally speaking, you should avoid fixed-size widths and height for this exact reason. You can leverage things like weighted chains in ConstraintLayout to size things proportionally instead of explicitly.
See the ConstraintLayout docs for more.
Hope that helps!
Your constraints are wrong. You have used both app:layout_constraintTop_toBottomOf and app:layout_constraintBottom_toTopOf constraints which is wrong. Use only app:layout_constraintBottom_toTopOf constraint to stack one above other.
Use this code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NewMainMenu"
tools:layout_editor_absoluteY="25dp">
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#android:color/holo_blue_light"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.494"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button4"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#android:color/holo_red_light"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button3"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#android:color/holo_green_light"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#android:color/holo_orange_light"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
</android.support.constraint.ConstraintLayout>
some codes is not right
please write below codes:
<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">
<Button
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#android:color/holo_green_light"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#android:color/holo_blue_light"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent" />
<Button
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#android:color/holo_orange_dark"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/button3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />

Android ConstraintLayout: Controls in ImageView mess up ImageView layout

I want to have two, side-by-side ImageViews that spread to take up 50% of the screen each. Over each, I want to arrange an array of Buttons and TextViews. I am doing this in a single ConstraintLayout.
When I set up the ImageViews by themselves, they lay out properly using these properties:
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
The ImageViews have constraints like this (there's also a 1dp View separator bar):
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/separator_bar"
app:layout_constraintTop_toTopOf="parent"
Here's what the split looks like:
However, when I add the Buttons and TextViews and chain them together, linking them to the sides of the ImageView and each other, making them essentially "contained" in the ImageView, the ImageView shrinks horizontally so that it is the width of the widgets, almost as if wrap_content were applied. What's even weirder is that the other ImageView also shrinks, even though I haven't added its widgets yet.
When marked up, the controls look like this:
<Button
android:id="#+id/btnKingW"
android:layout_width="42dp"
android:layout_height="42dp"
android:text="♔"
app:layout_constraintBottom_toTopOf="#id/btnQueenW"
app:layout_constraintEnd_toStartOf="#id/tvKingW"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="#id/white_king_image"
app:layout_constraintTop_toTopOf="#id/white_king_image"
app:layout_constraintVertical_chainStyle="spread" />
(the constraints of the original ImageView are unchanged)
Here's what it looks like with just one ImageView anchored to the parent on all four sides. The widgets look fine.
And here's the hot mess when I use the two ImageViews.
What's going on here? Why does linking a widget inside another widget/view cause the nice layout that I had before to change? I would assume that the ImageViews were anchored to the parent and shouldn't move, but this is clearly not the case.
I've looked at a bunch of tutorials, but they all seem to show me how to perform a half dozen tricks using the Android Studio GUI and don't really get into the zen of how the layouts are evaluated. I want to actually grok what's going on and not just click some buttons in a GUI design tool. FWIW, I did try the GUI design tool and spent about as much time cleaning up the magic trash it added to my XML (no, I don't need padding, thanks) as I would have saved using the tool, so I essentially abandoned it and now just use it to experiment.
I'm new to Android development, if that isn't clear. This is a toy app for an ungraded Udacity course.
Full 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.chessmaniac.MainActivity"
tools:layout_editor_absoluteY="81dp">
<ImageView
android:id="#+id/white_king_image"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:alpha="0.3"
android:contentDescription="#string/white_king_chesspiece"
android:scaleType="centerCrop"
android:src="#mipmap/white_king"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/separator_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/separator_bar"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/black_king_image"
app:layout_constraintStart_toEndOf="#id/white_king_image"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/black_king_image"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:alpha="0.3"
android:contentDescription="#string/black_king_chesspiece"
android:scaleType="centerCrop"
android:src="#mipmap/black_king"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/separator_bar"
app:layout_constraintTop_toTopOf="parent" />
<!-- WHITE BUTTONS -->
<Button
android:id="#+id/btnKingW"
android:layout_width="42dp"
android:layout_height="42dp"
android:text="♔"
app:layout_constraintBottom_toTopOf="#id/btnQueenW"
app:layout_constraintEnd_toStartOf="#id/tvKingW"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="#id/white_king_image"
app:layout_constraintTop_toTopOf="#id/white_king_image"
app:layout_constraintVertical_chainStyle="spread" />
<Button
android:id="#+id/btnQueenW"
android:layout_width="42dp"
android:layout_height="42dp"
android:text="♕"
app:layout_constraintBottom_toTopOf="#id/btnRookW"
app:layout_constraintEnd_toStartOf="#id/tvQueenW"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="#id/white_king_image"
app:layout_constraintTop_toBottomOf="#id/btnKingW" />
<Button
android:id="#+id/btnRookW"
android:layout_width="42dp"
android:layout_height="42dp"
android:text="♖"
app:layout_constraintBottom_toTopOf="#id/btnBishopW"
app:layout_constraintEnd_toStartOf="#id/tvRookW"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="#id/white_king_image"
app:layout_constraintTop_toBottomOf="#id/btnQueenW" />
<Button
android:id="#+id/btnBishopW"
android:layout_width="42dp"
android:layout_height="42dp"
android:text="♗"
app:layout_constraintBottom_toTopOf="#id/btnKnightW"
app:layout_constraintEnd_toStartOf="#id/tvBishopW"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="#id/white_king_image"
app:layout_constraintTop_toBottomOf="#id/btnRookW" />
<Button
android:id="#+id/btnKnightW"
android:layout_width="42dp"
android:layout_height="42dp"
android:text="♘"
app:layout_constraintBottom_toTopOf="#id/btnPawnW"
app:layout_constraintEnd_toStartOf="#id/tvKnightW"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="#id/white_king_image"
app:layout_constraintTop_toBottomOf="#id/btnBishopW" />
<Button
android:id="#+id/btnPawnW"
android:layout_width="42dp"
android:layout_height="42dp"
android:text="♙"
app:layout_constraintBottom_toBottomOf="#id/white_king_image"
app:layout_constraintEnd_toStartOf="#id/tvPawnW"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="#id/white_king_image"
app:layout_constraintTop_toBottomOf="#id/btnKnightW" />
<!-- WHITE TEXTVIEWS -->
<TextView
android:id="#+id/tvKingW"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WK"
app:layout_constraintBottom_toTopOf="#id/tvQueenW"
app:layout_constraintEnd_toEndOf="#id/white_king_image"
app:layout_constraintStart_toEndOf="#id/btnKingW"
app:layout_constraintTop_toTopOf="#id/white_king_image"
app:layout_constraintVertical_chainStyle="spread" />
<TextView
android:id="#+id/tvQueenW"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WQ"
app:layout_constraintBottom_toTopOf="#id/tvRookW"
app:layout_constraintEnd_toEndOf="#id/white_king_image"
app:layout_constraintStart_toEndOf="#id/btnQueenW"
app:layout_constraintTop_toBottomOf="#id/tvKingW" />
<TextView
android:id="#+id/tvRookW"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WR"
app:layout_constraintBottom_toTopOf="#id/tvBishopW"
app:layout_constraintEnd_toEndOf="#id/white_king_image"
app:layout_constraintStart_toEndOf="#id/btnRookW"
app:layout_constraintTop_toBottomOf="#id/tvQueenW" />
<TextView
android:id="#+id/tvBishopW"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WB"
app:layout_constraintBottom_toTopOf="#id/tvKnightW"
app:layout_constraintEnd_toEndOf="#id/white_king_image"
app:layout_constraintStart_toEndOf="#id/btnBishopW"
app:layout_constraintTop_toBottomOf="#id/tvRookW" />
<TextView
android:id="#+id/tvKnightW"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WN"
app:layout_constraintBottom_toTopOf="#id/tvPawnW"
app:layout_constraintEnd_toEndOf="#id/white_king_image"
app:layout_constraintStart_toEndOf="#id/btnKnightW"
app:layout_constraintTop_toBottomOf="#id/tvBishopW" />
<TextView
android:id="#+id/tvPawnW"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WP"
app:layout_constraintBottom_toBottomOf="#id/white_king_image"
app:layout_constraintEnd_toEndOf="#id/white_king_image"
app:layout_constraintStart_toEndOf="#id/btnPawnW"
app:layout_constraintTop_toBottomOf="#id/tvKnightW" />
</android.support.constraint.ConstraintLayout>
Try 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">
<ImageView
android:id="#+id/imageOne"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:src="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/imageTwo"
app:layout_constraintHorizontal_bias="0.65"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<ImageView
android:id="#+id/imageTwo"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:src="#color/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/imageOne"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="Button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/button2"
app:layout_constraintTop_toBottomOf="#id/guideline" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintLeft_toRightOf="#+id/button"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/guideline"
tools:layout_editor_absoluteY="232dp" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/button2"
app:layout_constraintTop_toBottomOf="#id/button" />
<Button
android:id="#+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintLeft_toRightOf="#+id/button"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/button2" />
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="87dp" />
</android.support.constraint.ConstraintLayout>
OUTPUT
Here is the good tutorial for this
First you have to arrange the image views correctly. Like the LinearLayout, you can set weight in ConstraintLayout.
<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">
<ImageView
android:id="#+id/imageOne"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:src="#drawable/img_one"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/imageTwo"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageTwo"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:src="#drawable/img_two"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/imageOne"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Then try to align button over the ImageViews. Hope it helps:)

ConstraintLayout in Cardview adding white space

I am trying to create a CardView that has a ConstraintLayout to organize some TextView.
Sometimes it'll display as intended, but sometimes, it'll add extra white space such as when a keyboard is closed and ruin the layout. I have a GIF below showing the CardView working and not working in the same span of time.
A code snippet for the relevant CardView is below. I use wrap_content to try to keep the CardView at the size I want, but it still expands.
<android.support.v7.widget.CardView
android:id="#+id/cardView_game_cash"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="6dp"
app:cardCornerRadius="4dp"
app:contentPadding="6dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView_game_cashLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Total Cash"
app:layout_constraintLeft_toLeftOf="#+id/textView_game_cash"
app:layout_constraintRight_toRightOf="#+id/textView_game_cash"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView_game_totalProfitLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Total Profit"
app:layout_constraintLeft_toLeftOf="#+id/textView_game_totalProfit"
app:layout_constraintRight_toRightOf="#+id/textView_game_totalProfit"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView_game_profitLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Win Profit"
app:layout_constraintLeft_toLeftOf="#+id/textView_game_profit"
app:layout_constraintRight_toRightOf="#+id/textView_game_profit"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView_game_cash"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/textView_game_totalProfit"
app:layout_constraintTop_toBottomOf="#+id/textView_game_cashLabel"
tools:text="TextView" />
<TextView
android:id="#+id/textView_game_totalProfit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:gravity="center"
app:layout_constraintLeft_toRightOf="#+id/textView_game_cash"
app:layout_constraintRight_toLeftOf="#+id/textView_game_profit"
app:layout_constraintTop_toTopOf="#+id/textView_game_cash"
tools:text="TextView" />
<TextView
android:id="#+id/textView_game_profit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:gravity="center"
app:layout_constraintLeft_toRightOf="#+id/textView_game_totalProfit"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="#+id/textView_game_cash"
tools:text="TextView" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
I found a solution to my problem. In the TextView within the ConstraintLayout, I replaced android:layout_height="wrap_content"
with:
android:layout_height="0dp"
app:layout_constraintHeight_default="wrap"
The layout worked as intended with that change to all the TextView within.

Categories

Resources