I have a RecyclerView includes 20 items from my rest api. When I add a new item to database, the first item in my list disappear and new one will add into the end of list by using mysql LIMIT 0,20
I want when I'm in the list and new item added, the scroll position doesn't change, so I used onSaveInstansceState before the adapter and onRestoreInstanceState after it. but as you can understand the new list has a difference with the older and that's the item position.So the list scroll one item more from its state.
How can I prevent this or is there another solution?
If you don't want the scroll position to change when adding an item, use notifyItemInserted().
// adapter
void addNewItem(Item item) {
itemList.add(item);
notifyItemInserted(itemList.size() - 1);
}
Related
Generally, I plan to use SwipeRefreshLayout and RecyclerView to implement Pull-To-Refresh list. After pulling the list to refresh the data, it seems that the original item position has been added one for refreshing widget. Since it is the position of the item that decides what kind of views should be drew or loaded, after refreshing, it was detected that the position of the same item was increased by 1, which directly leads to the IndexOutOfBoundException when I try to access the last item in the original list.
Is there any method that I can handle this position change so that the last item will be available without any exception?
I have a list of items. These items are sorted by date. Items with date before now ("old" items) should not be visible when user opens application but user should be able to see them by scrolling list to top.
I find position of first item with date in the future ("new" item) and call recyclerView.scrollToPosition(position).
I also tried layoutManager.scrollToPositionWithOffset(position, 0).
This works if there are many "new" items in the list.
But if there are too few items (for example, one "old" and one "new") then these methods do not work.
How can I scroll list programmatically to item at given position to place this item on top regardless of how many there are items in the list?
Initially, provide the RecyclerView with a dataset that has only the future events.
Set an onTouchListner on recyclerView to detect upward scroll. If findFirstCompletelyVisibleItemPosition() returns the first index when you detect an upward scroll, it means an upward overscroll. Then, change the data set to include the old entries. Then, use adapter.notifyDataSetChanged() to notify the adapter of the dataset change and list will be redrawn.
NOTE :
When you set onTouchListner on the RecyclerView make sure you
don't absorb the touch event [onTouchEvent() should return false].
Once, you've detected an upward overscroll for the first time,
you can set a flag to indicate that you don't need to change the
dataset for future touch events.
I am trying to add pagination in my listView.
I added a method in my custom BaseAdapter which adds next page results at top of list on scroll to first item in list.
public void addEntriesToTop(List<ChatModel> entries) {
// Add entries to the top of the list
this.chatMessages.addAll(0, entries);
notifyDataSetChanged();
}
So if I have to add next page on top of ListView, I am using like this in my activity.
//result contain new items to be added to top of list
adapter.addEntriesToTop(result);
//so that list scroll sets to last visible message to user
final int index = result.size();
listView.post(new Runnable() {
#Override
public void run() {
//go to user's last scroll position
messagesContainer.setSelectionFromTop(index, 0);
}
});
This method is working fine and retains user's last scroll position. But it has a problem, when I call addEntriesToTop() it scrolls the ListView to bottom(because of notifyDataSetChanged() ) and then when I call setSelectionFromTop it scrolls to user's last position. In this transition, there is small jerk.
Please help me to smooth this transition.
Thanks
As ListView is old and now its obselete, now you can use Recyclerview
instead of ListView, here is the link that helps you to convert your
ListView to RecyclerView. RecyclerView have many methods to add your custom animations and also it have not any jerks while adding/removing items.
Replacing ListView with RecyclerView
For Default Animations you can use this link:
RecyclerView Animations – Add & Remove Items
I am using the latest RecyclerView library to display a list with an option to add items to this list. The list is in reverse order, so newest additions are displayed at the bottom. When adding new items to a recycler view from the top, a nice animation is displayed and the list is automatically scrolled to display the newest item.
However, when adding new items from the bottom, items are not similarly pushed up as the new item is being animated. This leads to odd behavior where a new item is added and the animation cannot be seen unless the user scrolls to the bottom of the list.
As a temporary fix, I've forced the recycler view adapter to scroll to the first position after adding a new item. This isn't as seamless as adding from the top of a recycler view, is there a proper way to implement this?
The corresponding code is below:
la.addItem(0, msg);
layoutManager.scrollToPosition(0);
Add this function to your adapter class
public void addItem(Object aObject)
{
mAdapterList.add(aFormElement);
notifyItemInserted(mAdapterList.size()); // Passing position where insertion happen
}
If you are not getting animation than only use below function.
try to call scroll to position on recyclerview at your required position after calling addItem().
I am facing some difficulties getting the addition of new items in a ListView to appear at the top of the ListView. However, when new items are added to the ListView, I want the current item to remain visible and the new items to be added above it.
To that effect, I followed the solution from here: https://stackoverflow.com/a/3035521/450534 and when that did not work too, I started experimenting a little.
Also worth mentioning is that I am using the Pull to Refresh library by Chris Banes.
Now curiously, when I add paged data below the last item in the ListView, all works well. But I am stumped why new items will not be placed above the current item and maintain the current position. This is what I have done so far (in the onPostExecute()):
// GET THE CURRENT LISTVIEW POSITION (USED TO MAINTAIN SCROLL POSITION)
int currentPosition = actualListView.getFirstVisiblePosition();
Log.e("POSITION", String.valueOf(currentPosition));
View v = actualListView.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
Log.e("TOP", String.valueOf(top));
/***** APPEND NEW DATA TO THE ADAPTER AND THE LISTVIEW *****/
// CAST THE ADAPTER (AGAIN)
adapter = new NewsFeedAdapter(getActivity(), arrFeeds);
// SET THE ADAPTER TO THE LISTVIEW
actualListView.setAdapter(adapter);
// SET THE SCROLL POSITION
actualListView.setSelectionFromTop(currentPosition, top);
lv.onRefreshComplete();
This is the start of the ListView and this is what should still be seen after adding new items at the top (above this). I plan to show a small layout that shows how many new feeds are on top. Something like the Facebook app does now.
But new items are added to the bottom of the ListView instead of at the top above existing items.
Is there something obvious that I have missed? If you need me to add more code, please tell me and I will add it immediately.
another alternative would be to add the item at 0 poisiton of the ArrayList which you are using to populate the adapter.
your_array_list.add(int index, Object element) //Inserts the specified element at the specified position in this list.
and after adding you can call the notifyDataSetChanged() on your listAdapter.
Please confirm if it works..