Reputation: 5896
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>
Upvotes: 5
Views: 3465
Reputation: 22832
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>
Upvotes: 18
Reputation: 943
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>
Upvotes: 0
Reputation: 425
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
Upvotes: 0