I am using the RecyclerView firebase UI and found nothing realacionando the implementation of the infinite scroll. Today I'm looking for all the data from one node when loading the activity equal to firebase the code example, would leave more optimized this part request, seeking little data to be displayed and go loaded as user navigation.
There may be a workaround by adding a counter for each row in the database and to get them by
orderByChild("counter").startAt(10*n).endAt(10*(n+1));
n: 0 - item_count/10-1
I didnt try it but i believe it can be managed with database parameters.
Related
Hi I have some issue with calling firebase data from the server.
I can call the single child of data but if I call a nasty child of data(ex: multiple branch of child data), It is not working on kotlin side.
I used ".child()" function on Swift side by just adding ".child()" afterward and it worked on IOS side but I do not understand why the kotlin is not working like that.
Does anyone knows how to solve this problem? I've been searching this problem many days but nobody has a clear solutionenter image description here
Here the issue is of synchronous values, basically onDataChange is called on a different thread.. long story short try calling sectionRecyclerView.adapter line inside the for loop that or this will do the trick.
There's this question, which is identically worded.
But the poster's problem was solved without actually answering the question posted - because the problem was due to something unrelated to how the Paging Library knows to load more pages.
I'm wondering if the subscription/collection (Rx/Flow) mechanism used to consume the Paging datasource is how the Paging datasource knows when to load more pages. So maybe subscription/collection pulls pages. (But even so, how would pages after the initial load be triggered?)
And the datasource can use the pull events as an opportunity to check if it needs to load more pages.
I'm just speculating here because I don't know how this all works internally.
I'm hoping someone will either verify or dismiss my speculation and provide greater detail about the mechanism involved. In particular, when the Pages are exposed as a Flow or (Rx) Flowable.
The presenter API's .get(index) call is what triggers item access to the rest of Paging. Generally you need to call this function in order to bind items to a RecyclerView.Adapter, but leanback and compose work similarly.
On item access, an internal object called ViewportHint is sent which contains presenter-state including how many items post-transformation you can see and your current position in the list, which can be handled asyncly from rest of UI.
Paging then essentially triggers loads based on PagingConfig.prefetchDistance, but has a lot of logic handling race conditions, access conflation, cancellations, tracking load state, error handling, etc. which all can affect what ends up getting loaded in the end.
If you want to access but avoid triggering loads, there are .peek() and .snapshot() APIs that let you inspect presenter state without fetching.
There's a LOT of code in the Paging 3 library, and I desperately wanted to avoid having to look at it too closely.
But I did some superficial exploration and found a likely candidate to explain how loads of missing pages are triggered by the user scrolling.
Loads aren't, as I speculated in my question, triggered by the activity of the subscription/collection (Rx/Flow) of pages.
The adapter's attempt to get an item to display triggers a call to
PagingDataDiffer<T : Any>.get(#IntRange(from = 0) index: Int): T?.
Its Javadoc:
Returns the presented item at the specified position, notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.
Params:
index - Index of the presented item to return, including placeholders.
Returns:
The presented item at position index, null if it is a placeholder.
Of particular interest:
... notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.
So, there we have it.
If others disagree or wish to elaborate on the mechanism, please do so.
I have a list with pagination which I implemented using Paging library. Items on this list can be modified (changed/deleted).
According to official documentation, I'm first changing in-memory list cache from which my DataSource gets pages and after that calling datasource.invalidate() in order to create new pair PagedList/DataSource:
If you have more granular update signals, such as a network API signaling an update to a single item in the list, it's recommended to load data from network into memory. Then present that data to the PagedList via a DataSource that wraps an in-memory snapshot. Each time the in-memory copy changes, invalidate the previous DataSource, and a new one wrapping the new state of the snapshot can be created.
It works and looks WELL if user modifies items on first page.
However, if user is on page two or further during datasource.invalidate() he will be thrown at the end of the first page.
Debugging shows this happens because new PagedList has only first page when it's submitted to PagedListAdapter.submitList. Adapter compares old and new lists and removes all items not from first page. It happens always but not visible for user if he is on the first page.
So to me, it looks like new pair PagedList/DataSource have no idea about number of pages which fetched previous pair and datasource.invalidate() doesn't fit for the situation in docs. Behavior that I see acceptable for cases then user updates all list (like swipe-to-refresh) but not
an update to a single item in the list
Has anybody faced such issue or somehow archived things I want? Maybe I'm missing some trick which helps me to get new PagedList already with all pages.
For clarification: library version 2.1.0. Custom PageKeyedDataSource based on in-memory cache and remote servise (No Room)
I want to share my research in case anybody is interested:
Issue ("lack of feature") is known, at least I've found the couple related discussions on official tracker one two
If you are using PositionalDataSource or ItemKeyedDataSource you should dig into the direction of requestedStartPosition/requestedInitialKey from initial params as this answer says. I didn't have much time to build the whole solution but those params are indeed different for initial load after invalidation
About my case : PageKeyedDataSource. Here you can read that there is no similar to requestedInitialKey params in this type of data source. Still, I found a solution which fits me, very simple, although, feels like a dirty trick:
When loadInitial() is called after invalidate() in-memory cache returns all already loaded pages instead of just first one.
At first I was worry that something will break if, for example, requestedLoadSize is 5 but the result is 50 items list but turns out it's just a hint and it can be ignored. Just don't forget to pass nextPageKey which corresponds to the last cached page and not the first one.
Hope it will help
With observable method you will only get first page list items....if you want to edit other items you can get that list by adapter.currentlist method.
Example:
private fun list():MutableList<String>{
val list = mutableListOf<String>()
for (value in videosAdapter.currentList.orEmpty()) {
val abc = value.snippet.resourceId.videoId
list.add(abc)
}
return list
}
I have a project that loads a list from the server. This data will eventually be stored into a database, but for now is stored in memory in a MutableLiveData. A RecyclerView's adapter is watching the data and displaying it. So far everything is working as expected, using a FAB the user can post a new entry which will go at the top of the list, on success I get a 200 and here's the main part where I'm getting lost...
When I want to add a single item to a list stored in a LiveData, the observer is unaware of the delta. I currently make a call to RecyclerView.Adapter.notifyDataSetChanged(), though the ideal in my case would be to call notifyItemInserted(0) or in other cases I can see various other notifications. What the best way to do this? The lifecycle architecture library appears to be very well thought of, I assume I'm missing something simple. I can't imagine having to manually perform a diff between the lists?
How to create offline first RecyclerView in Android so the users still can see the list when they don't have any internet connection?
I already know how to get parse JSON and populate it in RecyclerView, the problem is, users still can't access it when offline. And if I use cache using SQLite, how to update only the latest data from the server?
for example, I already got 3 data from server and populate it in RecyclerView like this:
Data 3
Data 2
Data 1
After that, there is an update from the server so there are 4 data from the server. I only want to add the 4th data without load from the 1st. And its going to be like:
Data 4 --> only add this to the RecyclerView without reload past data
Data 3
Data 2
Data 1
Regards,
Elmer
I have done something similar in this project:
https://github.com/isaacurbina/MyMovies/blob/master/app/src/main/java/com/mobileappsco/training/mymovies/Fragments/ResultsFragment.java
Basically, I use an AsyncTask to load data as the user scrolls down, loading more content (kind of like 9GAG or Pinterest do) managing a "page" counter.
Then, as I receive the data, I join it to the List object using list.addAll(results), being results another ArrayList<> of the same kind.
Then you can use adapter.notifyDataSetChanged() on your RecyclerViewAdapter and it will add them super fast, or you can use an animation to show them being added slowly.
I hope it helps, kind regards!