How to set constant margin after last item in RecyclerView? - android

I want there to be some space after the last item in RecyclerView like the image.
The image is not in a state where the number of items is small, but in a state that is large enough to be scrollable.
In other words, when scrolling to the bottom, I want the last item to be positioned above the black bar of the image.
But what I have implemented is:
What I have implemented, as you can see in the image, is that the item penetrates the bar and is superimposed on the bottom.
When scrolling, it doesn't matter if the bar overlaps the item, but when scrolling to the bottom, I want the last item to be on top of the bar.
ADDITION:
These recycler views dynamically add and delete items.
For once you just post the XML code.
If you need other code, please tell me.
XML
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:background="#color/transparentBg"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/add_exercise"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="8dp">
<ImageView
android:id="#+id/add_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/ic_add"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="#color/black" />
<TextView
android:id="#+id/add_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="ADD ROUTINE"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/add_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

If you want your items to be displayed beneath the add Icon (which I personally do not like) and add some extra space in the bottom you can
Add an empty view to the end of your adapter
set clipToPadding=false and add a bottom padding which make the recycler view to skip that amount of height from bottom, but still show them (not clipping them) like this (I'm not sure if 160dp is a good number sum up your dimensions)
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toTopOf="parent"
android:clipToPadding="false"
android:paddingBottom="160dp"/>
And if you want your recycler to be shown above the add button (which I think looks better) you can change it like this
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/button" />

You can set your FrameLayout to a specific height and then give your recyclerview margin bottom same as frame layout height.
Or you can just change your ConstraintLayout into a LinearLayout.

Related

Fluid height RecyclerView when full or empty

I have a dynamic recycler view. Which expands the height of its parent when full and looks really nice however when there are no entries added to it yet or there are few entries in it it just looks ugly.
However if I set the width to say 200dp than it looks a bit better.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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/shading"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?android:attr/actionBarSize"
android:background="#color/shading">
<ImageView
android:id="#+id/logo"
android:layout_width="120dp"
android:layout_height="60dp"
android:src="#drawable/ic_logo"
app:layout_constraintBottom_toTopOf="#+id/list_projects"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list_projects"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="20dp"
android:background="#drawable/shape_list_item_projects"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/logo" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="#color/white"
app:fabCradleRoundedCornerRadius="25dp"
app:fabCradleMargin="5dp"
app:hideOnScroll="false"
app:menu="#menu/menu_main_activity" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_outline_add_circle_outline_24"
app:backgroundTint="#color/white"
app:layout_anchor="#id/bottomAppBar"
app:maxImageSize="40dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
The desired outcome is to have it wrap the content until it reaches the bounds of BottomAppBar.
You can do that by:
Bias the RecyclerView to the top using ConstraintLayout vertical chain:
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="packed"
This makes the RecyclerView directly under the top image, and pack both to the top of the layout.
Force the RecyclerView default height dimension to wrap_content:
app:layout_constraintHeight_default="wrap"
This makes the RecyclerView to wrap its content when having 0 or few items until it reaches the bounds of BottomAppBar; then the RV will be strict to the constraint.
Remove app:layout_constraintBottom_toTopOf="#+id/list_projects" from the top image to make the top image and RecyclerView aligned to the top (not centered vertically).

How can I ignore the remaining screen to show other rows? Recyclerview

The Row
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="2.5dp">
<com.google.android.material.card.MaterialCardView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintWidth_percent="0.5"
tools:ignore="MissingConstraints">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
I want every row to take 50% from the screen and everything works well but the remaining screen will be empty because I set ConstraintLayout as match_parent I tried to change it to wrap_content but not working.
How can I ignore the remaining screen to show other rows?
The problem is something like this

How to keep progressbar always below a recyclerView and not to be squeezed out of screen if there are too many items?

I am making a layout for showing scanned bluetooth device. Here is the 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"
tools:context=".fragments.ScannedListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_scan_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/progressBar_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:itemCount="12"
tools:listitem="#layout/list_item_scanned_list" />
<ProgressBar
android:id="#+id/progressBar_scan_list"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/recycler_view_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
But when there are too many list items, the progressbar will be squeezed out of the screen. Just like this:
demonstration1
I want to keep the progressbar stick to the bottom of the recyclerView when the screen has enough space to show all content and the progressbar can be completely shown above the bottom of the screen without scrolling even if there are too many items in the recyclerView.
I tried vertically chaining two views and packed chain with bias but no luck. Also, I found that adding app:layout_constraintHeight_max="" for the recyclerView can achieve similar effect. But it seems not a general solution for different screen sizes.
Create a vertical chain by constraining the bottom of the ProgressBar to the parent, then set the chain style to packed so that both views stick together and then set the vertical bias to 0 to align them to the top of the parent. To prevent the RecyclerView from pushing the ProgressBar out of the screen set the app:layout_constrainedHeight="true" attribute for the RecyclerView - it enforces constraints when the height is set to wrap_content.
<?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=".fragments.ScannedListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_scan_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="0"
app:layout_constrainedHeight="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/progressBar_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:itemCount="12"
tools:listitem="#layout/list_item_scanned_list" />
<ProgressBar
android:id="#+id/progressBar_scan_list"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/recycler_view_scan_list"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.ScannedListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_scan_list"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/progressBar_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:itemCount="12"
tools:listitem="#layout/list_item_scanned_list" />
<ProgressBar
android:id="#+id/progressBar_scan_list"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This way it will be always visible. Make the progress bar bottom constraint to parent and recycler view height 0dp

ConstraintLayout & FrameLayout wrap_content then FrameLayout show half content

I don't known why FrameLayout inside ConstraintLayout, and both use wrap_content, then the last item in the RecycleView just show half content.
If I remove FrameLayout, direct use recycleview, it can work!
<?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="wrap_content"
android:background="#drawable/finance_bg_book_list_dialog">
<TextView
android:id="#+id/tvToolbarTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/finance_bg_book_list_toolbar"
android:drawablePadding="10dp"
android:padding="14dp"
android:text="#string/finance_book"
android:textColor="#android:color/white"
android:textSize="?fontSizeLarge"
app:drawableStartCompat="#drawable/finance_ic_toolbar_shelf"
app:layout_constraintBottom_toTopOf="#+id/vulturLayout"
app:layout_constraintTop_toTopOf="parent"/>
<FrameLayout
android:id="#+id/vulturLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvToolbarTitle">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_contentCode="successful"/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
You need some horizontal constraints on your textview.
ex : app:layout_constraintStart_toStartOf=
I recommend you set a dimension for the RecyclerView height. if you use the FrameLayout with a wrap_content height, your RecyclerView will not be scrollable and it will own show half the item at the last based on the screen size

Horizontal Recycler View with dynamic content in Scroll View. When the content is more than the viewport, vertical scroll is not working

I have a Horizontal Recycler View in a Scroll View.
The content of the items in the Recycler View is dynamic, meaning that their height is different.
When the content exceed the height of the viewport, the content is clipped at the bottom.
The layout of the Recycler View:
<androidx.core.widget.NestedScrollView 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:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="true"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</RelativeLayout>
</androidx.core.widget.NestedScrollView>
I have tried many different solutions:
Set different ViewGroups as the Nested Scroll View child
Set android:nestedScrollingEnabled to true/false
Tried with ConstraintLayout and 0dp heights and using app:layout_constrainedHeight="true"
And other than I cannot recall.
The layout of the item looks as such:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:padding="30dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
android:background="#android:color/black"
android:padding="20dp"
android:text="#{text}"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
And a demonstration of the issue:
At the end of the dummy text there should be a [END].
In the beginning it's visible and after a while not.
https://youtu.be/iX1jhihgNx0

Categories

Resources