How to split large json array into pages in Android - android

I'm fetching json data from https://jsonplaceholder.typicode.com/photos, and want to split this data into pages so that I can implement the Android Paging Library in my app. Does anyone know how I can achieve this?

Page 1 (returns photos for id 1 to 10):
https://jsonplaceholder.typicode.com/photos?_start=0&_limit=10
Page 2 (returns photos for id 11 to 20)
https://jsonplaceholder.typicode.com/photos?_start=10&_limit=10

For paginatio you will use android jetpack
https://developer.android.com/topic/libraries/architecture/paging
Another method
get specific number of data from api and add into recyleview after that do something like below after loading your specific data again you will call further remaining specific data make a counter for counting loaded data.
getalltemlist() is a method from where u get ur json.
Reference https://www.youtube.com/watch?v=2-vZ1g_G1Zo
boolean isScrolling=false;
rView.setAdapter(adapter);
rView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int
newState) {
super.onScrollStateChanged(recyclerView, newState);
if(newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL)
{
isScrolling=true;
}
}
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
currentitems=layoutManager.getChildCount();
totaliitems=layoutManager.getItemCount();
scrolloutitems=layoutManager.findFirstVisibleItemPosition();
if(isScrolling && (currentitems + scrolloutitems == totaliitems))
{
isScrolling=false;
getAllItemList();
}
}
});
adapter.notifyDataSetChanged();
getAllItemList();

Related

Implement Load More in RecyclerView with PairList using MVP pattern

I'm looking for best practices. I want to implement load more [progressbar] after every 10 items (Using RecyclerView).
In past, I did this by simply creating Loader class item and just added into the specific position in my List. Well, this time, I'm using PairList and it's impossible to add Loader class item (even tho I personally think, that's a pretty clean way to do it).
I found a few solutions on SO, which are almost the same: How to implement load more recyclerview in android
Is there any other way I could implement this load more progressbar after every 10th element (First load 10 items from API, then, when user reaches 10th item, we show progress bar [meanwhile we fetch the next 10 items], remove progress bar, add 10 items and so on).
Use this InfiniteScrollListener in your recycler scrollListener:
public abstract class InfiniteScrollListener extends RecyclerView.OnScrollListener {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager)recyclerView.getLayoutManager();
int visibleItemCount = linearLayoutManager.getChildCount();
int totalItemCount = linearLayoutManager.getItemCount();
int pastVisiblesItems = linearLayoutManager.findFirstVisibleItemPosition();
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loadMore();
}
}
}
protected abstract void loadMore();}
recyclerView Listener:
recyclerView.addOnScrollListener(new InfiniteScrollListener() {
#Override
protected void loadMore() {
boolean willLoad = //get your last api call data. if empty set false
int offset = recyclerView.getAdapter().getItemCount();
if(willLoad){
willLoad=false;
onCallApi(offset,10);
}
}
});
your api:
private void onCallApi(int offset,int limit){
//your api
}

ListView scroll up for refresh, scroll down to add new items to the list

Right now I have a Listview that stores 25 items, which are retrieved from an API. What I want is that the ListView refreshes on scroll up (retreive data from api call again). And add another 25 items on scroll down.
What could I use for this?
I found SwipeRefreshLayout, However, I can't find a way to distinguish scroll up and scroll down.
Use RecyclerView instead of ListVIew. Initialize the RecyclerView as follows :
RecyclerView Initialization :
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
videosAdapter = new VideosAdapter();
recyclerView.setItemAnimator(new SlideInUpAnimator());
recyclerView.setAdapter(videosAdapter);
// Pagination
recyclerView.addOnScrollListener(recyclerViewOnScrollListener);
Now setup OnScrollListener :
private RecyclerView.OnScrollListener recyclerViewOnScrollListener = new
RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
if (!isLoading && !isLastPage) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0
&& totalItemCount >= PAGE_SIZE) {
loadMoreItems();
}
}
}
};
Once you get the response you need to add the received data to the list again.
I think your question is little bit misleading.If i am not wrong, here can be to thing.
Reload List on Over Scroll Down :- This functionality can be achieve by using SwipeRefreshLayout. Follow the android tutorial for Adding Swipe-to-Refresh To Your App.
Load more items on Over Scroll Up:- This is the part of Lay loading(Pagination) . If you are using ListViewthen you can use OnScrollListener and setFooterView() to make it done . Have a look at This thread.
Suggestion:- A simple suggestion Use RecyclerView instead of ListView to make better use of ViewHolder pattern.

How to perform pagination with the Litho framework?

I am implementing a Retrofit APi for getting data from the server and showing this in a RecyclerView using the Litho framework, and it's doing well. As all of us know when we have infinite data to show in recyclerview we have to implement the pagination pattern. And I know this, but I am confused how to implement this in the Litho framework. Litho the provides onScrollListener() method:
final Component component = Recycler.create(context)
.binder(recyclerBinder)
.onScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//
})
.build();
I don't know: how to use a customized EndlessRecyclerViewScrollListener for endless scrolling in Litho?
I have had success implementing the "infinite" scroll pattern leveraging the recyclerBinder within the onScrolled method of a OnScrollListener. A trivial example would be the following:
//Initialize the RecyclerBinder
recyclerBinder = new RecyclerBinder(c, new LinearLayoutInfo(getContext(), OrientationHelper.VERTICAL, false));
//Initialize a recycler component
Component component = Recycler.create(c)
.onScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// use the recyclerBinder to determine what items at what position are visible -
// (you could also use the findLastVisibleItemPosition() method depending on your implementation)
int firstVisibleItemPosition = recyclerBinder.findFirstVisibleItemPosition();
//check if it is within range relative to the current available items and is not loading (room to improve/modify logic pending use case)
if((recyclerBinder.getItemCount() - 5) <= firstVisibleItemPosition && !isLoading) {
//if so - use your service to get the next page
service.getNextPage();
}
}
})
.build();
Then in a call back method - you can insert your items starting at the item count
public void callback(List<T> results) {
int position = recyclerBinder.getItemCount();
for(T result: results) {
Component component = //assemble your component(s) ...
ComponentInfo.Builder info = ComponentInfo.create().component(component);
recyclerBinder.insertItemAt(position, info.build());
position++;
}
}

Firebase load data dynamically on scrolling

I need know how to load data dynamically on scrolling with Firebase. If I query data with Firebase, all data must be loaded once time or always data changed. I want load data with Firebase per limit, and after reach this limit, load more data and more and more.
It would basically be like a timeline of Facebook - as a social network.
For example: I want to get the latest records from Firebase at limit 50. After reach this limit, I will download the next 50 data. I would like use RecyclerView and not FirebaseRecycler class.
FirebaseRecyclerAdapter not solve my question. Thanks for help. Trully, i need loadind data like facebook timeline of point view layout, and load data Firebase (50 to 50. Download 50 data, reach limit, load more data of bottom layout to 50) of point view Database.
Could you help me?
This works perfectly fine.
Infinite-Scroll-Endless-Scrolling-Tutorial
private RecyclerView recyclerView;
boolean userScrolled=false;
private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
LinearLayoutManager mLayoutManager;
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mLayoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
// Implement scroll listener
public void implementScrollListener() {
recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView,
int newState) {
super.onScrollStateChanged(recyclerView, newState);
// If scroll state is touch scroll then set userScrolled
// true
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
userScrolled = true;
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx,
int dy) {
super.onScrolled(recyclerView, dx, dy);
// Here get the child count, item count and visibleitems
// from layout manager
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager
.findFirstVisibleItemPosition();
// Now check if userScrolled is true and also check if
// the item is end then update recycler view and set
// userScrolled to false
if (userScrolled
&& (visibleItemCount + pastVisiblesItems) == totalItemCount) {
userScrolled = false;
RefreshData(oldestPostId);
}
}
});
}
Firebase has FirebaseRecyclerAdapter for connecting RecyclerView directly to firebase database. See FriendlyChat sample app from google for details: https://github.com/firebase/friendlychat
you can use startAt(), endAt(), and equalTo() method, official link enter link description here
// Find all dinosaurs that are at least three meters tall.
var ref = firebase.database().ref("dinosaurs");
ref.orderByChild("height").startAt(3).on("child_added", function(snapshot) {
console.log(snapshot.key)
});
answered:
https://stackoverflow.com/a/41583467/1429832

How can I identify that RecyclerView's last item is visible on screen?

I have one RecyclerView and I added list of data into the RecyclerView. I wanted to add more data in list, when last RecyclerView item is visible on screen. After that I want to make a web service call and update the RecyclerView data. How can I achieve this?
Any suggestions?
One option would involve editing your LayoutManager. The idea here is to find the position of the last visible item. If that position is equal to the last item of your dataset, then you should trigger a reload.
#Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
final int result = super.scrollVerticallyBy(dy, recycler, state);
if (findLastVisibleItemPosition() == mData.length - 1) {
loadMoreData();
}
return result;
}
#Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
if (findLastVisibleItemPosition() == mData.length - 1) {
loadMoreData();
}
}
Alternatively, you could do this via your adapter's onBindViewHolder method, although this is admittedly a bit of a "hack":
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position == mData.length - 1) {
// load more data here.
}
/// binding logic
}
3rd option would be to add an OnScrollListener to the RecyclerView. #velval's answer on this page explains this well.
Regardless which option you go for, you should also include code to prevent the data load logic from triggering too many times (e.g., before the previous request to fetch more data completes and returns new data).
If someone stumble across this post this is a quick and simple tutorial on how to do it:
All you need to do is:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = lm.getChildCount();
int totalItemCount = lm.getItemCount();
int firstVisibleItemPosition= lm.findFirstVisibleItemPosition();
// Load more if we have reach the end to the recyclerView
if ( (visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
});
Then your loadMoreItems() should look something like this:
private void loadMoreItems() {
// init offset=0 the frist time and increase the offset + the PAGE_SIZE when loading more items
queryOffset = queryOffset + PAGE_SIZE;
// HERE YOU LOAD the next batch of items
List<Items> newItems = loadItems(queryOffset, PAGE_SIZE);
if (newItems.size() > 0) {
items.addAll(newItems);
adapter.notifyDataSetChanged();
}
}
Seen many of the above answers but my answer is different one and it will work in your cases also. My approach is based on scroll state of recylerview. Maintain below variable "check" and this should update only once when api responds. Put below code in your api response. If you want to handle last item only on every call of api.
final boolean[] check = {true};
recyclerView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (!recyclerView.canScrollVertically(1)) {
// last item of recylerview reached.
if (check[0]) {
//your code for last reached item
scroll_handler.setVisibility(View.GONE);
}
} else {
scroll_handler.setVisibility(View.VISIBLE);
check[0] = false;
}
}
});
If you want to handle your last item every time then do it as below
recyclerView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (!recyclerView.canScrollVertically(1))
// Bottom of recyler view.
arrow_img.setRotation(180);
}
}
});
See also Android - Detect when the last item in a RecyclerView is visible.
private fun isLastItemVisible(): Boolean {
val layoutManager = recycler_view.layoutManager
val position = layoutManager.findLastCompletelyVisibleItemPosition()
return position >= adapter.itemCount - 1
}

Categories

Resources