Android RecylerView EndlessScroller on load more, jumps to top - android

I am using endless scroller with recylerview and it is loading products at bottom but always on load more call my page starts from top not from bottom.
Am I doing something wrong? I am using https://gist.github.com/ssinss/e06f12ef66c51252563e as an endless scroller and my code in activity is:
recyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
#Override
public void onLoadMore(int current_page) {
String load_more_url = url + "&page=" + String.valueOf(current_page);
bottamProgressBar.setVisibility(View.VISIBLE);
productVolleyLoader = new ProductVolleyLoader(getApplicationContext(), load_more_url,productList,
myAdapter,bottamProgressBar, productRecyclerView);
productVolleyLoader.volleyLoader();
}
});

Very Sorry for this silly question. Actually I was setting adapter in volley loader instead of there I have to set adapter in onCreate method and in volley loader I just have to use notifyDataSetChanged();.
After that scrolling is working fine.

At the end of the "onLoad" method, call:
mRecyclerView.smoothScrollToPosition(lastPosition);
Getting the last position from the view with mRecyclerView.getChildCount() or something like that if each item is a child inside the RecyclerView. Save it to a variable on the begining, so you'll have the last position before the load and scroll there on the end of the load.

You are adding the new values in the old list in load more. So every time its a new list.
You will have to programmatically scroll to the last position of the view.
When you are calling for load more, save the position and when list loads, scroll to that position programmatically.

Related

how to make recycler view not scroll back to top after update

I have recycler view with datas that when it on the bottom with this code findLastCompletelyVisibleItemPosition() it will load new data. my init data and my load data are the same function just add change the body request after recyclerview scroll to very bottom. My issue is when it load a new datas it will scroll back to top. how do I make it in the same place and not scroll back?
I already tried to impelemnt this in load data function
val recyclerViewState =list_view_history_program.layoutManager?.onSaveInstanceState()
if (loadMore > 0) {
listAdapter.notifyItemRangeChanged(loadMoreCount, listAdapter.itemCount, programNames)
listAdapter.notifyDataSetChanged()
list_view_history_program.layoutManager?.onRestoreInstanceState(recyclerViewState)
list_view_history_program.scrollToPosition(loadMoreCount)
}
but still it scroll back. please help
You already used notifyItemRangeChanged then used notifyDataSetChanged. Remove listAdapter.notifyDataSetChanged()
Use below code after add item in itemList array
NOTE : but you must call adapter the first time then second time use the below code
adapter.notifyItemInserted(itemList.size());

Horizontal RecyclerView with DiffUtil issue

I have a RecyclerView with horizontal items. These items have fix 150dp height and 100dp width.
When the Fragment is loaded, than I set default items to this view.
After that, I make a Room getImages() call, when the result arrive than I rebuild this RecyclerView.
As you see in the GIF :
Default images loaded (2 with play button, 3 with pro image)
Add getImages() result
The result is inserted before the 1st default item
Play button cards have fix id actually ("-1") and pro have another fix ("0") and every image item have unique id.
The new item is added before the first item, and the user don't see it. The RecyclerView won't scroll to first item.
There is any solution push the first item to right when a new one added to 1st place??
I tried the smoothScrollToPosition but it won't work after submitList() and maybe where is any better solution.
All you have to do is use Recyclerview's smooth scroller
smoothScroller = new LinearSmoothScroller(this) {
#Override
protected int getHorizontalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_ANY;
}
};
then when you want to scroll to first position of recyclerview
smoothScroller.setTargetPosition(0);
horizontalLayoutManagaer.startSmoothScroll(smoothScroller);
Try to use scrollToPosition(0) instead.
If that won't work, try whether adding a small delay is fixing it, like so:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
recyclerView.scrollToPosition(position); // Or maybe `smoothScrollToPosition()`
}
}, 300); // Try a delay of 200 or 300 ms

detect scroll down in listView android

I have a requirement
I have a large data have to put in the list view and it's too stupid to load all data and populate in list view so i load 10 first item from server and populate in listView.
So everytime user scroll down at the bottom of listview ( They viewed all first 10 item ) my app will load the next 10 item automatically.
Problem is : Is there anyway that i can detect that whether user is at the bottom of the first 10 item or not ?
Sorry about my English . appreciate for any help !
You can detect the end of scrolling by the following code
if (yourListView.getLastVisiblePosition() == yourListView.getAdapter().getCount() -1 &&
yourListView.getChildAt(yourListView.getChildCount() - 1).getBottom() <= yourListView.getHeight())
{
//It is scrolled all the way down here
}
Hope it helps.
You can register a listener to the OnScroll event and then detect where you have to start reloading data:
ListView listView = (ListView)findViewById(R.id.list_view_id);
listView.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int amountVisible, int totalItems) {
//now get the point where you have to reload data
if (firstVisibleItem+1 + amountVisible > totalItems) {
//reload your data here
}
}
});
Where's the data coming from ? It's common to load large data sets from a DB via a cursor, and then use a simple cursor adapter to populate the list view. (And I'm talking 10,000s of rows). So long as you do it in the background (cursor loader) it shouldn't be a problem, and it probably a lot easier than trying to manage the scrolling yourself.
Try this, it implements a listview that pulls more items when the user reaches the bottom, also using a progressbar in the bottom when is loading more items.
I have used it before and it works well for what you need.

Is there a way to prevent the listview from scrolling to its top position when its adapter's data is changed?

I'm having a bit of trouble preserving the scroll position of a list view when changing it's adapter's data.
What I'm currently doing is to create a custom ArrayAdapter (with an overridden getView method) in the onCreate of a ListFragment, and then assign it to its list:
mListAdapter = new CustomListAdapter(getActivity());
mListAdapter.setNotifyOnChange(false);
setListAdapter(mListAdapter);
Then, when I receive new data from a loader that fetches everything periodically, I do this in its onLoadFinished callback:
mListAdapter.clear();
mListAdapter.addAll(data.items);
mListAdapter.notifyDataSetChanged();
The problem is, calling clear() resets the listview's scroll position. Removing that call preserves the position, but it obviously leaves the old items in the list.
What is the proper way to do this?
As you pointed out yourself, the call to 'clear()' causes the position to be reset to the top.
Fiddling with scroll-position, etc. is a bit of a hack to get this working.
If your CustomListAdapter subclasses from ArrayAdapter, this could be the issue:
The call to clear(), calls 'notifyDataSetChanged()'. You can prevent this:
mListAdapter.setNotifyOnChange(false); // Prevents 'clear()' from clearing/resetting the listview
mListAdapter.clear();
mListAdapter.addAll(data.items);
// note that a call to notifyDataSetChanged() implicitly sets the setNotifyOnChange back to 'true'!
// That's why the call 'setNotifyOnChange(false) should be called first every time (see call before 'clear()').
mListAdapter.notifyDataSetChanged();
I haven't tried this myself, but try it :)
Check out: Maintain/Save/Restore scroll position when returning to a ListView
Use this to save the position in the ListView before you call .clear(), .addAll(), and . notifyDataSetChanged().
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
After updating the ListView adapter, the Listview's items will be changed and then set the new position:
mList.setSelectionFromTop(index, top);
Basically you can save you position and scroll back to it, save the ListView state or the entire application state.
Other helpful links:
Save Position:
How to save and restore ListView position in Android
Save State:
Android ListView y position
Regards,
Please let me know if this helps!
There is one more use-case I came across recently (Android 8.1) - caused by bug in Android code. If I use mouse-wheel to scroll list view - consecutive adapter.notifyDataSetChanged() resets scroll position to zero. Use this workaround until bug gets fixed in Android
listView.onTouchModeChanged(true); // workaround
adapter.notifyDataSetChanged();
More details is here: https://issuetracker.google.com/u/1/issues/130103876
In your Expandable/List Adapter, put this method
public void refresh(List<MyDataClass> dataList) {
mDataList.clear();
mDataList.addAll(events);
notifyDataSetChanged();
}
And from your activity, where you want to update the list, put this code
if (mDataListView.getAdapter() == null) {
MyDataAdapter myDataAdapter = new MyDataAdapter(mContext, dataList);
mDataListView.setAdapter(myDataAdapter);
} else {
((MyDataAdapter)mDataListView.getAdapter()).refresh(dataList);
}
In case of Expandable List View, you will use
mDataListView.getExpandableListAdapter() instead of
mDataListView.getAdapter()

Add more items in ListView when we scrolled down it

I have a custom listview(with two image and 5 textviews) in which I have to show more than 200 data when I load it at first time with all data then it returns out of memory exception, to resolve the same problem I want that when we scrolled down the listview till the last item of the list then it app again adds more data to the same list. It running as same till we have got all the data on the list view. Please don't tell me to use EndlessAdapter because Endlessadapter always downloading the items after each 10 seconds. Which returns also the outof memory after some time.
Thanks in advance.
assign a List http://developer.android.com/reference/java/util/List.html to your addapter then you can call item.add and item.remove
please try this
endless listView
Thanks
I'd recommend that every time a user scrolls you check the position of the first element of the ListView.
ListView.getFirstVisiblePosition()
If it's close to the amount of the elements in your list you can add items to the bottom of the list and remove the ones from the top of the list.
I did something like this to load in more elements when the user scrolled down on an ExpandableListView once.
myListView.setOnScrollListener( new OnScrollListener()
{
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
int lastVisibleElement = firstVisibleItem + visibleItemCount;
if(lastVisibleElement == totalItemCount)
{
//Load elements
myListAdapter.notifyDataSetChanged();
}
}
about out of memory , there is no way that 5 imageViews and 5 textViews will cause out of memory . you are probably saving all of the 200 images together instead of using some sort of caching (like softreference and LruCache) . the whole point of the adapter is to show tons of items (not at the same time , of course) using minimal memory . you can see that even the play store (which i still like to call android market) app uses memory cache if you play enough with scrolling ...
for more information about listview, watch this
you might also want to read more about handling images here .
anyway , you can take the getView as a trigger (using the position parameter compared to the getCount() value) to when to load more items and then update the adapter using notifyDatasetChanged (and update the getCount() value) .

Categories

Resources