RecyclerView with LinearLayoutManager with header view that doesn't recycle - android

I want a ListView style RecyclerView with a header on top, AND I don't want the header view to get recycled, EVER.
I'm totally new to RecyclerView and LinearLayoutManager but I think what I want shouldn't be too difficult by extending LinearLayoutManager.
Additional info in case needed, but I think the above is enough:
I already have a RecyclerView with a header view at position 0. That part was easy enough with help from SO answers. But the view gets recycled, which is causing lots of issues with the EditText views in the header (trying to keep focus, restore focus, keep the caret visible, not do weird things with auto-correct feature, keep typing while EditText is technically gone/recycled, etc). So the simple solution would be to not have that view recycled, which I think is possible with a custom layout manager, but I have no idea where to begin.
I can't simply place the header view above my list, because I want it to scroll with the list (it's too tall to be fixed at the top of screen all the time).

LayoutManager has LayoutManager#ignoreView(View) interface which according to documentation,
Flags a view so that it will not be scrapped or recycled.
Looks like what you need here
EDIT Google devs commented (here) that this flag is serving some other purpose, so it is not gonna solve "RecyclerView Header" problem. However, they are working on solution, so hold on tight and stay tuned

Related

Reusing Android views in a LinearLayout

I'm making sort of a news feed, that is displayed below a static menu. To avoid the news feed from being scrolled in the tiny bit of space that's left after the menu, I wanted to scroll both the menu and the newsfeed at the same time.
Now I'm realizing this with a LinearLayout, so it doesn't scroll itself like the listview. But my question is, is using a LinearLayout, which from what I know doesn't reuse views like a listView, bad practice? How likely am I to get into memory issues, since the news feed can have A LOT of views, and they all contain images.
Many thanks!
Apparently there is a pretty good chance for you to get an OutOfmemmoryexception in no time with this approach,If you want to go with re-using the views
I suggest you should go with the new RecyclerViews in Android,
Go here for a tutorial on recycler views
I don't know if this qualifies to be an answer. But if you are using a LinearLayout with a header view and a ListView inside it, then there are no issues. Since the main worry you have is the news feed which would be recycled by the ListView. Neglecting to use view recycling is asking for trouble, and will likely break after 50 or so (Android hates images).
As for the header that must disappear. I would avoid putting it as the first item in a ListView as suggested in the comments, and rather have it static in the LinearLayout. And use a view translation and/or transparency to hide it. This keeps the option availible to display the header at any point, regardless of the list's scroll.

RecyclerView detaches view still visible

Current scenario
I'm using this library https://github.com/kanytu/android-parallax-recyclerview to achieve a parallax effect on a RecyclerView. So far, so good. However I would like get an effect like Google Newsstand where the header is still bellow the cards.
Problem
The problem is that RecyclerView (or LinerLayoutManager) detaches the header view the moment the first element of the list touches the top of the parent view:
As you can see the moment the first cardview touches the top is the moment RecyclerView detaches the header.
I'm sure that there is no problem on the logic itself I get RecyclerView.findViewHolderForPosition(0) == null when the card reaches the top. Proving that the header is recycled.
Tried Solutions
I tried many things like:
ViewHolder.setIsRecyclable using this method to set the holder to not recycler doesn't do any effect.
LayoutManager.ignoreView I tried marking the view to be ignored from being discarded and recycling. The result was an exception saying:
Trying to recycle an ignored view holder. You should first call stopIgnoringView(view) before calling recycle.
setItemViewCacheSize Doesn't do anything. Tried calling setItemViewCacheSize(50) and it doesn't do anything to the header.
setMaxRecycledViews Tried setting the max of recycled views with viewType=HEADER to 0 and it still recycles it.
Conclusion
So I question if there is anyway to mark the item for not getting detached until I order so (like checking if it's still visible and then detach it).
There is also an issue on the github about it: https://github.com/kanytu/android-parallax-recyclerview/issues/7
You can use the new design support library's CoordinatorLayout with your recyclerview and make the same effect with no issues like this.
check this link: http://android-developers.blogspot.com/2015/05/android-design-support-library.html

Make Header View (not Section Header) of ListView Stick on Top

I have a ListView with a HeaderView.
I want one of the views in the HeaderView to stick on top.
I've seen a lot of examples for sticky Section Headers.
I also looked at StickyScrollViewItems but since I'm using a ListView, I cannot use a ScrollView.
Is there a library available for this or should I just override the OnScrollListener of the ListView?
Thanks.
I have just written a load of code that does this that I cant share for contractoral reasons. Basically follow the approach outlined here and apply to a listview rather than a scroll view.
Main points are
Create a wrapper view that contains your floating/sticky header and your listview as siblings
Use a proxy method when adding headers with an isSticky boolean - if is sticky then add a fake blank header to the listview of the same size and your intended header view to the floating header wrapper (use a relative layout here)
Set a scroll listener of the listview that tracks the top px position of the dummy header view in the list and setting this as a top margin of the floating header that sits inside a relative layout
Handle all the annoying edge cases / OEM overscroll crap to get it to work in all situtions (like this for samsung)
Remember to set the initial position of the floating/pinned header after the listview has been layed out.
I feel its a little bit involved and takes some tweaking to get right - this is a time where i envy iOS and any iOS devs will think your slacking as it takes a while to implement :D
All the Open libs out there at time of writing are using scroll views or list view headers. This issue with these approaches are that list views recycle views (so unlike scroll views you cant just keep a ref to the dummy view) and also the current libs seem duplicate the sticky views using adapter getView methods and so on - which is no good for dynamic list view header views as they are not recycled and can only have one parent, so reparenting would be annoying (and in my case has a lot of functionality so I defo dont want to create two views of the same type and shoehorn the current libs to fit my solutions)
I don't know of any library that lets you do this but what I do for a header is to use a RelativeLayout for my xml that will have the ListView. Then create your header view however you want and give it the property
android:layout_alignParentTop="true"
then give your ListView
android:layout_below="#id/idOfHeaderView
This is the easiest way I know of to dock a header view at the top. It has worked for me every time. I hope this helps.

ListView slowing down ViewPager swipe

I have a ViewPager that contains ImageViews downloaded from the net and it slides just fine when my ListView (in another separate layout) is not initialized.
But the problems start when my ListView is created. The ViewPager still "slides" but only slides about 1/4 of the way, lags, then loads the next ImageView correctly.
All of the network and bitmap operations are done using AsyncTask. I've also used the RemoteImageCache API from Singly API which works pretty well.
Any ideas as to why ViewPager's swipe is lagging?
The slow down was caused by the ListView calling getView more than necessary (more than 3x per item in my list).
According to this solution, the ListView's width and height must be given specific values and not wrap_content or else getView() will be called multiple times.
it's just because of list view scroll is conflict with view pager scroll..
if you want to know about this just set list view visibility gone don't remove code listView.setAdapter(adapter) then try view pager will slide properly.
Recently (2020), must be to implement a ViewHolder class to you get speed, or, refactoring with RecyclerView, it depends of the size of your list and the time that you have to execute this methods, like my software was already production stage, i preferred use ViewHolder class, the speed gain came to be 40%, sufficient to me, if you need the more speed, must be to use RecyclerView (refactoring your listview, edit .xml, your adapter, use Linear or Grid layout manager...).

How to synchronize content of one view depending on scroll position in sibling ScrollView?

I have extended LinearLayout (vertical) to create a custom compound component. This in turn contains two children:
one custom view that is drawn directly onto the view canvas.
one HorizontalScrollView->LinearView(Horizontal)->Multiple custom views.
I would now like to redraw the custom view to match the visible contents of the scroll view. The reason for this is that the long array of custom components in the scroll view are mainly static and suitable to be drawn ahead of time, while the top view is supposed to be highly dynamic and relate to whatever things are visible in the scroll view.
I hope I made the problem/idea somewhat clear. I am not att all confident this is the best approach, and I'd enjoy hearing any suggestions on alternative solutions or perhaps some idea on how to trigger a redraw-event everytime the scroll position changes in the HorizontalScrollView.
Thank!
You can have your activity listen to the scroll view adapter. in the adapter when ever the scroll position changes you execute the delegate in the Activity.
That way the activity can update the rest of the views upon scroll view change.

Categories

Resources