Center horizontally with only one View for constraint - android

Is there a way, using ConstraintLayout to achieve the below, without setting an invisible View on the right side as well? (The right back arrow should be invisible, I've made it visible to make things easier to understand)
The middle view currently is as follows:
<RelativeLayout
android:id="#+id/cover_wrapper"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="#dimen/_10sdp"
android:onClick="#{(view) -> viewModel.onAutoPlayButtonClick()}"
app:layout_constraintStart_toEndOf="#id/back_button"
app:layout_constraintEnd_toStartOf="#id/dummy_button"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/buttons_wrapper"
app:layout_constraintDimensionRatio="3:4">
Besides simply setting a right margin calculated as button_width + button_margin_left + button_margin_right, is there a trick to not have the right View there and not use margins either?

Yes you can achieve that using ConstraintLayout and Guidelines without setting any invisible View
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/grey"
>
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toStartOf="#+id/guideline2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="#color/green"
android:background="#color/white"
android:padding="10dp"
app:srcCompat="?attr/actionModeCloseDrawable" />
<View
android:layout_width="0dp"
android:layout_height="200dp"
app:layout_constraintStart_toStartOf="#+id/guideline2"
app:layout_constraintEnd_toEndOf="#id/guideline3"
app:layout_constraintTop_toTopOf="#id/imageView"
/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".3" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".7" />
</androidx.constraintlayout.widget.ConstraintLayout>

Related

Android: Show button just below to the recylerview but always on the screen

On the screen, I want to show RecyclerView which start from the top and at the end of the RecyclerView, there is a button.
When RecyclerView is not occupying the entire screen then the Button will sit just below the RecyclerView.
When RecylerView is scrollable then in this case button will sit on the bottom of the screen.
I tried this code. But the problem here, RecyclerView sits in the centre. In my case, it will always start from the top(after the action bar).
Following code I tried:
main 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="match_parent"
android:background="#b6d7a8" >
<LinearLayout
android:id="#+id/actionBarTermsAndCondition"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/dark_gray"
android:gravity="center_vertical"
android:minHeight="70dp"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingTop="10dp"
android:paddingEnd="16dp"
android:paddingBottom="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<ImageView
android:id="#+id/closeButton"
android:layout_width="#dimen/spacing_2x"
android:layout_height="#dimen/spacing_2x"
android:layout_gravity="center_vertical"
android:layout_marginEnd="#dimen/spacing_2_5x"
android:clickable="true"
android:contentDescription="#string/close"
android:foreground="?selectableItemBackground"
android:src="#drawable/cross"
android:visibility="invisible" />
<TextView
android:id="#+id/route"
style="#style/ScreenTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="Import Venue"
android:fontFamily="#font/roboto"
android:text="Import Venue"
android:textColor="#color/white"
tools:text="Something" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:name="DataManagementFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="LinearLayoutManager"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#id/constraint_layout_cloud_access"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/actionBarTermsAndCondition"
app:layout_constraintVertical_chainStyle="packed"
tools:itemCount="3"
tools:listitem="#layout/fragment_data_management_list_row" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraint_layout_cloud_access"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FEAB8C"
android:paddingStart="16dp"
android:paddingTop="10dp"
android:paddingBottom="21dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/list">
<TextView
android:id="#+id/text_cloud_access"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/roboto"
android:text="Cloud access"
android:textColor="#3C3C41"
android:textSize="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Cloud access" />
<TextView
android:id="#+id/text_import_venue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/roboto"
android:text="Import venue"
android:textColor="#3C3C41"
android:textSize="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/text_cloud_access"
tools:text="Import place" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
RecyclerView row 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:background="#fff2cc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="#dimen/spacing_3x"
android:paddingStart="#dimen/spacing_2x"
android:paddingBottom="#dimen/spacing_2_5x"
android:paddingTop="#dimen/spacing_2_5x"
android:orientation="horizontal"
tools:showIn="#layout/fragment_data_management">
<TextView
android:id="#+id/text_floor_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/roboto"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="#3C3C41"
android:textSize="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Preloaded" />
<TextView
android:id="#+id/text_venue_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/roboto"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="#636367"
android:textSize="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/text_floor_name"
tools:text="ABC" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="?android:attr/listChoiceIndicatorMultiple"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="?attr/dividerHorizontal" />
</androidx.constraintlayout.widget.ConstraintLayout>
Your RecyclerView is centering between two other layouts. Add
app:layout_constraintVertical_bias="0.0"
to the XML for the RecyclerView to move it to the top. You can look up how bias works in the ConstraintLayout documentation.
I think you can achieve what you want with a guideline. The steps would be the following:
Create an horizontal guideline that sits at the 90% of the screen, meaning that it will be really close to the bottom, on the 10% left is where your button will be when the recycler view becomes scrollable.
Set the bottom constraint of the recycler view to match the top of the guideline and the top of the recycler view to the top of the screen. This will cause that the recycler view appears on the half of your screen.
Set the vertical bias of your recycler view to 0.0, this will stick the recycler view to the top.
Set the top constraint of the button to match the bottom of the recycler view, this will cause that it will stick to the bottom of the recycler view, but since the recycler view (thanks to the guideline) will only grow to 90% of the screen, the button will sit at the bottom of the screen as you want.
It's important to add the following attribute to the recycler view:
app:layout_constrainedHeight="true"
The layout related to the button and recycler view should look something like:
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintVertical_bias="0.0"
tools:itemCount="130"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button text"
app:layout_constraintTop_toBottomOf="#+id/list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.9"/>
</androidx.constraintlayout.widget.ConstraintLayout>
With few items:
With many items:

RecyclerView pushes its below button out of the screen in ConstraintLayout

I am attempting to set up a layout with an "X" button pinned to the top of the screen, and then two elements centered in the view. One a recycler view and then, pinned below the recycler view, a button for form submission. The layout I currently have worked until the recycler view outgrows its bounds. Then the submission button is pushed below the bounds of the view and the recycler view does not stay within the layout. How can I center the two recycler and button views but not have the button go past view bounds if the recycler view grows large?
View With Small Recycler View Appears As (it should be centered. my example is slightly off.)
How View Should Appear with Larger Recycler View (the recycler view's content is too large to fit so it scrolls)
How View Actually Appears with Larger Recycler View (the recycler view does scroll, but now it pushes the button off the bottom of the view, which appears as the button being cut off)
Relevant Code Block for XML Layout
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.45"
android:orientation="vertical"
android:background="#color/backgroundLightSecondary"
android:padding="20dp" >
<Button
android:id="#+id/bt_close"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="end"
android:background="#drawable/ic_close"
android:textColor="#color/textLightPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center_vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_item_options"
android:layout_width="match_parent"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:id="#+id/bt_order"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_weight="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:background="#drawable/bt_rounded_corner"
android:fontFamily="#font/microbrew_two"
android:padding="3dp"
android:text="#string/btn_add_to_order"
android:textColor="#color/backgroundLightSecondary"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
In such cases, the best way is to use a ConstraintLayout as the container. As you mentioned in the question, you want to lay the RecyclerView at the center. So, it leads to binding its top and bottom to the buttons.
On the other hand, if we make a chain between the RecyclerView and submitButton with a vertical chain style of packed, the submitButton would stick to the bottom of RecyclerView (which height is wrap_content to be able to grow) and moves with its bottom until it reaches the bottom of the screen (because of app:layout_constraintBottom_toBottomOf="parent").
The key point is to set app:layout_constrainedHeight="true" for the RecyclerView leading to not overlap with the two buttons.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp" >
<androidx.appcompat.widget.AppCompatImageButton
android:id="#+id/closeImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_baseline_close_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#id/submitButton"
app:layout_constraintTop_toBottomOf="#id/closeImageButton"
app:layout_constraintVertical_chainStyle="packed" />
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/recyclerView" />
</androidx.constraintlayout.widget.ConstraintLayout>
Visual Result:
As I understand You want a button on top followed by recyclerview and than a Submit button in the end.And if size of recyclerview grows Submit button should not change its place.
Try this I make a rough layout
<LinearLayout //This is root layout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycle"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
Output of code looks like this
You can do everything you want in just one hierarchy by using ConstraintLayout. As an example, I edited your XML code as below;
<?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/bt_close"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#drawable/ic_close"
android:textColor="#android:color/white"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_item_options"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="#+id/bt_order"
app:layout_constraintTop_toBottomOf="#+id/bt_close" />
<Button
android:id="#+id/bt_order"
android:layout_width="150dp"
android:layout_height="50dp"
android:background="#android:color/holo_blue_dark"
android:padding="3dp"
android:text="Button"
android:textColor="#android:color/white"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/rv_item_options" />
</androidx.constraintlayout.widget.ConstraintLayout>

Constraint Layout Vertical Align Center - Two Child Views

I have two TextViews, one above the other. I would like the vertical middle of the two TextViews to be at the same position as the vertical middle of the ImageView. (This is so, regardless of the amount of text that may go into either TextView, everything will always look neat, vertically.)
I created what I need perfectly using two LinearLayouts (as the space above the title is the same as the space beneath the description):
But Android Studio was unable to covert it to ConstraintLayout successfully, as it just dumped the TextViews at the bottom of the layout. I've played with a lot of attributes, but could not quite arrive at the desired layout.
My question is similar to this one, except that I am trying to center_vertical align a pair of views rather than a single one - which means I have no view edge to align to the centre of the ImageView/container.
Is it possible to achieve what I'm after with ConstraintLayout? (I expect I may be able to do it with a single RelativeLayout, but I would like to use the layout_constraintDimensionRatio attribute on my ImageView which presumably leave me needing to use ConstraintLayout.)
In case it helps, here's the code for my aforementioned LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="#dimen/resources_list_image_size"
android:layout_height="#dimen/resources_list_image_size"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:layout_gravity="center_vertical"
android:contentDescription="#string/resource_image"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="#+id/textViewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/MyTextAppearanceMedium"
tools:text="Title" />
<TextView
android:id="#+id/textViewDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/MyTextAppearanceSmall"
tools:text="Description" />
</LinearLayout>
</LinearLayout>
Update: Solution
Thanks to Ben P's answer, this is my final code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Add guideline to align imageView to. -->
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.3" />
<ImageView
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="#string/resource_image"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/guideline"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="#+id/textViewTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
app:layout_constraintBottom_toTopOf="#id/textViewDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/imageView"
app:layout_constraintTop_toTopOf="parent"
android:textAppearance="#style/MyTextAppearanceMedium"
app:fontFamily="#font/roboto_slab_regular"
app:layout_constraintVertical_chainStyle="packed"
tools:text="#string/enter_title_colon" />
<TextView
android:id="#+id/textViewDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/imageView"
app:layout_constraintTop_toBottomOf="#id/textViewTitle"
app:fontFamily="#font/roboto_slab_light"
android:textAppearance="#style/MyTextAppearanceSmall"
tools:text="Description" />
</androidx.constraintlayout.widget.ConstraintLayout>
It sounds like you could solve this problem by using a packed chain anchored to the top and bottom of the ImageView. You'll also need to use horizontal bias and a constrained width in order to get wrapping to work correctly.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/anchor"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="64dp"
android:background="#caf"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="#id/anchor"
app:layout_constraintStart_toEndOf="#id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#id/two"/>
<TextView
android:id="#+id/two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_bias="0"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="#id/one"
app:layout_constraintStart_toEndOf="#id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#id/anchor"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The important attributes here are:
app:layout_constraintVertical_chainStyle="packed" on the first view, which causes the two textviews to stack right on top of each other
app:layout_constraintHorizontal_bias="0" on both views, which means that when the text is not long enough to reach the edge of the screen it will stick to the edge of the anchor view
app:layout_constrainedWidth="true" on both views, which prevents the textview from ever being wider than its constraints, and so the text wraps to a new line
If you want to use ConstraintLayout you could use something like this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:contentDescription="description"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="#+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toTopOf="#+id/imageView">
<TextView
android:id="#+id/textViewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Title" />
<TextView
android:id="#+id/textViewDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Description" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
You can use this layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/colorAccent"
android:text="I am 5% of the screen height"
app:layout_constraintBottom_toTopOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="#+id/textView3"
app:layout_constraintHeight_percent="0.05"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="#+id/textView3"
app:layout_constraintTop_toTopOf="#+id/imageView2" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.15"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="#color/colorPrimary"
android:text="I am 15% of the screen height (And the image is 20% screen size in height) "
app:layout_constraintBottom_toBottomOf="#+id/imageView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView2"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.20"
app:layout_constraintDimensionRatio="1:1"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/rose" />
</android.support.constraint.ConstraintLayout>
It will look like this:
One important thing about this layout:
You can control your aspect ratio (for the image) with app:layout_constraintDimensionRatio="x:y" and by passing "1:1" make it square
And by the way - I am using support library for no reason on this example, you can use androidx

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>

app:layout_marginBottom is not working well with android constraint layout

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

Categories

Resources