How to add a simple 8dp header/footer to Android's RecyclerView? - android

Is there a way to add a simple header/footer to a RecyclerView?
Here you can see what I've got. The first Card touches the Toolbar
And here you can see what I would like to achieve:
8dp Padding between the bottom and the Card.
Methods I tried so far:
Use a header view in my recyclerview. But I think it is very inefficient to do this for every recyclerview.
use a 8dp top margin which results in the problem that the recyclerview has white bars on top/bottom when scrolling.
add a padding to the list item which results in different margins between the outer and inner cards.
I'm sure that there is a simple solution which I don't know so far.

Adding a top padding and setting clipToPadding to false will do the trick.
Something like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:paddingTop="8dp"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />

If you are using a RecyclerView with a layout_weight, and paddingBottom is not working for you, making sure you set the layout_height to 0dp! Otherwise, strangely, paddingTop works but paddingBottom does not:
<android.support.v7.widget.RecyclerView android:id="#+id/recycler"
android:paddingBottom="20dp"
android:clipToPadding="false"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />

Related

Border in RecycleView Android

I'm using RecycleView, there shouldn't be a border after each item in the recycle view, but I have. How to remove it? I think the problem is in the LayoutManager because there is not border in the last element of RecycleView
<androidx.recyclerview.widget.RecyclerView
android:background="#color/menu_background" //here is non border
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
tools:listitem="#layout/cabin_category_info_layout" />
And it's CardView
<androidx.cardview.widget.CardView 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:layout_marginTop="20dp">
If you use CardView you should know that there's a default corner on this View so if you don't want it you should configure it to don't show it.
Try adding this into your CardView
app:cardCornerRadius="0dp
Also if you want to remove the elevation you may use this too
app:cardElevation="0dp"
The cardview by default has elevation which depicts as a border. You can either remove the card view or you can make the elevation as 0dp.
app:cardElevation="0dp"

How to add space below scroll view

I have wrapped an activity in an scroll view like following.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>
<include layout="#layout/content_form" />
</ScrollView>
I have around 15 fields in the content_form layout, the issues is that the last item in content_form layout is attached with bottom.
I need to add a margin below the scroll view, i have tried giving margin to scrollviewand the last item of content_form field, but nothing is working.
I need to know how to add margin at the bottom of page when using scroll view.
If you want the scrolling margin to be within the content, it would be best to add it to content_form. You should be able to accomplish this by either adding paddingBottom to your parent container in that layout, or layout_marginBottom on your last view aligned to the parent bottom.
This make padding under the last item in scroll view. may be good for you
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:paddingBottom="80dp"
android:clipToPadding="false"
android:layout_height="match_parent">
You can either use Space or View for the purpose like
<Space
android:layout_width="100dp"
android:layout_height="match_parent"/>
Or,
<View
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
Here, you need to give padding, not margin.
Try giving padding to the ScrollView.
I've had issues with ScrollView being ill-behaved when it's direct childview is not a LinearLayout. So please try LinearLayout as direct child of your scrollView and place <include> layout inside LinearLayout.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
... your layouts go here ...
</LinearLayout>
</ScrollView>

Shadow on CardView within ConstraintLayout not showing

I have a CardView within a ConstraintLayout.
This view is then inflated and added to a LinearLayout.
I would like the CardView to cast a shadow on the next CardView, but it seems to be clipped by the ConstraintLayout. How can I get the elevation shadow to show on the CardView without providing more padding or margins for it?
i.e. How can I cast the shadow on an adjacent item?
<LinearLayout>
<ConstraintLayout>
<CardView> <-- This view's shadow is cut
...
</CardView>
</ConstraintLayout>
<ConstraintLayout>
<CardView>
...
</CardView>
</ConstraintLayout>
<LinearLayout>
Try adding this comment inside your card view that's enough
card_view:cardUseCompatPadding="true"
How can I get the elevation shadow to show on the CardView without providing more padding or margins for it?
i.e. How can I cast the shadow on an adjacent item?
You can't, for both a practical reason and a conceptual one.
The practical reason comes down to how the Android framework draws CardView shadows. On older API levels, the card is inset within its own bounds and that extra space is used to draw the shadow. So even if you had two cards immediately next to each other, they'd still have "space" between them due to these insets. From the documentation:
Before Lollipop, CardView adds padding to its content and draws shadows to that area.
On Lollipop and higher, shadows are drawn within the parent's bounds, not within the CardView's bounds. Still, the parent will clip the shadow if there isn't enough space between the card's edges and the parent's edges to draw the whole shadow. In your example, each CardView is in a separate parent, so even if you put those parents immediately next to each other, each parent would still clip its card's shadow.
As for the conceptual reason, that's just not how shadows work (in nature). If you have two cards at the same elevation, even if they're right next to each other, the top card wouldn't cast a shadow on the bottom card.
Try to add
app:cardElevation="10dp"
In order to use app:cardElevation you have to add to your LinearLayout:
xmlns:app="http://schemas.android.com/apk/res-auto"
I tried this in a test project and the elevation should work this way. Below is my code:
<?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="ro.helpproject.funcode.help.MainActivity">
<android.support.constraint.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="50dp"
app:cardElevation="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TEST TEST" />
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="50dp"
app:cardElevation="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TEST TEST" />
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
</LinearLayout>
CardView needs padding around it for shadow to appear.
If app:cardUseCompatPadding="true" adds the shadow for you but you don't want the extra padding from 4 directions (LRTB), you need to add margin to the CardView yourself.
Enable Developer options -> Show layout boundaries and if you see that there is no empty space around your CardView. Then that's probably the reason shadow not appearing.

Recycle can not scroll inner ScrollView

I hava a layout below:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</android.support.v7.widget.RecyclerView>
the recyclerView using LinearLayoutManager, a item of recyclerView is another recyclerView which using GridLayoutManager, set the gridLayoutRecyclerView's height, but the gridLayoutRecyclerView can not scroll inner
try this code
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
and also refer about this http://developer.android.com/training/material/lists-cards.html
After checking implementation, the reason appears to be the following. If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and gets equal to minimum height (as per implementation) which is apparently zero.
You have couple of options for fixing this:
Set a certain height to RecyclerView
Set ScrollView.fillViewport to true
Or keep RecyclerView outside of ScrollView.
If RecyclerView height is not limited - which is the case when it's put into ScrollView - then all Adapter's views have enough place vertically and get created all at once.
This is my out recyclerView's layout
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</android.support.v7.widget.RecyclerView>
then, a item of out recyclerView have another RecyclerView's which using GridLayoutManager, this is the code of the item below:
<android.support.v7.widget.RecyclerView
android:id="#+id/seatRecyclerView"
android:layout_width="match_parent"
android:layout_height="200dp"
/>
the seatRecyclerView can't not to scroll

Making StaggeredGridLayout wrap content

I need to display a staggered grid within a linear layout.
For that I have used a StaggeredGridLayoutManager on a RecyclerView from android.support.v7.widget. The problem is that StaggeredGridLayoutManager doesn't support wrap_content.
There are other questions addressing the issue, but they are concerned with linear layouts, not staggered grids:
Not able to add empty view below Recyclerview
How do I make WRAP_CONTENT work on a RecyclerView
As far as I understand I could derive StaggeredGridLayoutManager and implement onMeasure. Is there a way do to that without recalculating the positions and sizes of the children myself? When looking at the StaggeredGridLayoutManager.java source, I can see that it uses ScrollbarHelper to approximate the size of the scrolling content. Is there a way to reuse that?
The problem is that when RecyclerView is drawn, it calculates all the remaining size to itself before drawing the next elements and don't recalculate after the other elements are drawn, leaving them outside the screen.
There is an easy fix for this problem: The trick is to draw all other elements first, and leave RecyclerView for last. Use a relative layout and put the RecyclerView last on the XML layout file. Since with relative layout you can put each element wherever you want independently of the order on the XML file, you will draw all elements before RecyclerView and this will make it calculate the accurate remaining space and wrap_content will work properly.
Example to add a paginagion bar below the RecyclerView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity"
>
<LinearLayout
android:id="#+id/pagination_btns"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"> //HERE YOU ALIGN THIS ELEMENT TO THE BOTTOM OF THE PARENT
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/previous_btn_label"/>
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/next_btn_label"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/items_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:layout_above="#id/pagination_btns"/> //HERE YOU ALIGN THE RECYCLERVIEW ABOVE THE PAGINATION BAR
</RelativeLayout>
I ended-up using a custom control for this, inspired by:
https://github.com/expilu/AntipodalWall/blob/master/library/src/com/antipodalwall/AntipodalWallLayout.java

Categories

Resources