RecyclerView with wrap_content is not animating well - android

When I have my RecyclerView height as wrap_content, as below
<android.support.v7.widget.RecyclerView
android:id="#+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
The result as below.
The is because the resize happens before the animation.
It is described more clearly in
https://medium.com/#elye.project/recyclerview-supported-wrap-content-not-quite-f04a942ce624#.n7xivnrdr
Is there a way to force it to animate first then only resize?

Related

Constraint layout Not constraining correctly

I have a layout activity in my project in which I am using a constraint layout and basically only 3 view, first is custom toolbar second a Recycler View and last one is a fragment view. I constrained recycler view to top toolbar and top of fragment view but I goes below fragment and even under screen.
This is my layout 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="match_parent"
android:theme="#style/Theme.Music.Font">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/header_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/bold"
android:text="#string/app_name"
android:textSize="26sp" />
<androidx.appcompat.widget.SearchView
android:id="#+id/searchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
app:searchIcon="#drawable/search_icon" />
</androidx.appcompat.widget.Toolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbarThumbVertical="#drawable/scroll_bar"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nowPlaying"
android:name="com.example.music.NowPlaying"
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"
tools:layout="#layout/fragment_now_playing" />
</androidx.constraintlayout.widget.ConstraintLayout>
And when I constrained with fragment also it goes on top overriding toolbar.
As shown in picture.
When you use wrap_content for the height or width, you're saying the view should expand to be as large as necessary to "display" the content. "Display" in air quotes because if there's a lot of content, parts of the view might end up off the screen.
Your constraints don't limit the size here, just the positioning. If you constrain one edge to something, you'll pin it, and it will expand off the screen at the other end. If you constrain opposite edges, then you're basically centering it around those constraints.
If you want to match those constraints, you need to set the height to 0dp. That way your constrained edges will actually be pinned where you want them, and that makes the view a certain height. It fits the space between its constrained edges.
Looking at your layout, I'm guessing the "now playing" part at the bottom is your FragmentContainerView. That's set to wrap_content but its contents seem to be a fixed size, so that's fine - exactly what you want! Same goes for the toolbar - it's wrap_content, but its contents are a fixed size.
So your RecyclerView also needs its bottom to be constrained to the top of nowPlaying, and it needs a layout_height of 0dp. That way, it's constrained to the space between the toolbar and the now playing bit, and its size fills that area. The other two take up as much space as they need, and the RecyclerView fills what's left - which is what you want, right?
Generally this is how it works for anything that scrolls, like a RecyclerView or ScrollView - the view in the layout is a window into the scrolling content, so the actual size of the view (layout_height and layout_width) controls the size of that window. The content just scrolls up and down behind it. If that window is the same size as the content, wrap_content, then the whole thing is visible (but possibly off the screen) and there's nothing to scroll! So for scrolling stuff, you always want to limit the size of the view.

RecyclerView item align left

I have a tags_frame in the FoodCardFragment (whose layout can be found here) that is used for displaying a RecyclerView in the TagsFragment. The layout of TagsFragment is simply:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start" />
The RecyclerView uses either StaggeredGridLayoutManager or LinearLayoutManager. However, as you can see from the middle of my cardview, this RecyclerView (composed of round-corner rectangles) uses StaggeredGridLayoutManager and it is centered. And actually in another activity I used LinearLayoutManager it is also centered.
How can I align it to the left (start) of the card?
You can try this in your fragment_tags.xml:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recycler_view"
android:layout_width="wrap_parent"
android:layout_height="match_parent"
android:layout_gravity="start" />
Use wrap_content for layout_width.
This happens because you are constraint your FrameLayout to parent on both sides and set width as match_parent. You have more options, One is to set gravity start to your framelayout or set width of the framelayout as wrap_content and constraint only to start.

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

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

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" />

Categories

Resources