Endless Scrolling List View in android - android

I am displaying list of records using List View. I am loading records when user scroll to end.
Here my problem is records is loading but scroll goes to first record every time and how to end when records all are loaded.

You mean when the user reaches the bottom of the ListView you load additional data, but then the ListView jumps back up to the top of the ListView?
That is probably because you reset the adapter. Try modifying the data source of the adapter and then calling notifyDataSetChanged() on the adapter like this:
In your Adapter you have some kind of datasource like a list of all items, create a public getter for these items:
public List<ListViewItem> getItems() {
return this.items;
}
Then when you load additional items you get the list from the adapter and add your items:
List<ListViewItem> items = adapter.getItems();
items.addAll(newItems);
And after that you call notifyDataSetChanged() to tell the adapter that you changed the datasource:
adapter.notifyDataSetChanged();

Related

Is there an event called by changing the count of items in the recyclerview?

Is there an event called by changing the count of items in the recyclerview?
I want to call function every time recyclerview items are added.
Update:
It turns out I misunderstood the original question. What was really asked is how to get notified when the underlying data in an Adapter has changed.
For this you could use a RecyclerView.AdapterDataObserver in conjunction with RecyclerView.Adapter's registerAdapterDataObserver(AdapterDataObserver observer) method to register for changes in the underlying list data.
Original Answer:
Your RecyclerView is backed by a RecyclerView.Adapter which owns the actual list of items being displayed.
If you change the backing list, you should call one of the notifyXXX methods on your adapter to notify your RecyclerView what has changed (and optionally where in the list the change happened.)
At the very least, you could call notifyDataSetChanged on your adapter to tell your RecyclerView that something somewhere in the list has changed. This can be expensive since you're not being specific about what changed, so the RecyclerView has to query the adapter for more information and potentially redraw its entire client area of items.
Something like:
RecyclerView.Adapter adapter = recyclerView.getAdapter();
if (adapter != null) {
adapter.notifyDataSetChanged();
}
Behind the scenes, the RecyclerView will call the RecyclerView.Adapter#getItemCount() method on the Adapter to determine what the current item count is.

Update all items in a RecyclerView asyncronsously on Android

I have a recycler view I want to update one attribute of each item after the initial creation to provide the user with a nicer experience. I would like to do this asynchronously as it takes time to get the data.
How do you iterate over the items in a recycler view and subsequently update. I moved from listview to recycler because it has a the method NotifyItemChanged.
So Ideally I would like to do
void OnRefresh(IList<data> data)
{
Data = data;
NotifyDataSetChanged();
Task.Run(() => UpdateAllAttribute1Fields());
}
void UpdateAllAttribute1Fields()
{
foreach(var myItem in myRecyclerView.Items)
{
UpdateAttribute1(myItem));
}
}
But I do not understand how to access myItems. On windows (sorry), in a listview this would be listview.items I think.
I could save the views OnBindViewHolder but that will be a bit more work.
Thanks all.
You dont need to iterate over all items in recyclerview to update, Just set the RecyclerView to point to your custom data set. And asynchronously update the data set whenever you want. You can then notify the recyclerview that the data in the dataset has changed with the following methods of its adapter (which will automatically update the recyclerview content)
adapterObj.notifyItemChanged(pos) //for one object
adapterObj.notifyDataSetChanged() //for the entire dataset
adapterObj.notifyItemRangeChanged(start, end) //for a range

Should we pass a copy of the items to RecyclerView, so that when we filter, we don't remove from the actual list?

I have 10 items in my activity.
They are displayed in a RecyclerView.
The itms are stored in a list;
List<CustomItem> items = new ArrayList<>();
I pass them to the RecyclerView adapter like so:
recyclerView.setAdapter(new RVAdapter(this, items));
Now, whenever I do filter the items by a string query, so that the
recycler view displays a subset of the items by description, for instance,
I have to pass a filtered list of items to the recycler view, like so:
List<CustomItem> filteredItems = CustomItem.filterByQuery(items, query);
and then I:
adapter.setItemList(filteredItems);
notifyDataSetChanged();
-> which sets the filtered items in place of the items I sent to it in the constructor, and effectively overrids the activity items because they both point to the same objects in memory.
And I realized that by filtering in order to display a subset of results, I am overriding the acitivy's list of items, because it is shared by the activity and the RecyclerView
However, of all the code samples and tutorials I've seen on RecyclerView, I've never seen anyone do a deep copy of the list of items and pass it to the RV, so what am I missing here?
I found the answer in the comments below the accepted answer here:
How to filter a RecyclerView with a SearchView
To quote:
#LalitThapa Just look at the constructor of my ExampleAdapter above. The second line should be interesting for you because that's where I make a copy of the List passed into the Adapter. What you want to have is two separate Lists. One in your Activity or Fragment which contains all items and a second List in your Adapter which contains only the filtered icons. Your problem is that you use the same List instance for both. – Xaver Kapeller Jan 17 at 19:05

Update ListView when updated list has got from server

How dynamically update the content of ListView?
App gets list from server and shows it. Also app caches this list for showing it to the user without delay. Somewhere in the future app will get updated list (update is small: two items was added, one was deleted).
How to detect changes and update only these items in ListView? Is there any complete solution?
If you are using ArrayAdapter, you can use .add(), .addAll(), .remove() to change data of the Adapter. And then call .notifyDataSetChanged() to refresh the view in the GUI.
Here are codes to refresh ListView when its data source is changed.
List<Something> lists;
And your Adapter should like this:
public MyAdapter extends BaseAdapter{
private List<Something> mLists;
public MyAdapter(List<Something> lists){
mLists = lists;
}
...
}
And initialize Adapter:
MyAdapter adapter = new MyAdapter(lists);
listView.setAdapter(adapter);
And when lists changes and you want to refresh ListView, call like this:
adapter.notifyDataSetChanged();
or:
listview.notify();
Then you will see your ListView is changed.

How to show All list items in child ListView-using cwac-merge-1.0.4 jar

I am using two ListView in same screen,Because of using two Listviews likely Parent ListView and Child ListView,that Child ListView Adapter class doesn't show all List Values in Child ListView.It showed only 0 th(first) position in Child ListView,for this above issue I have used the answer code from this Android list view inside a scroll view link.now I can see all list values in my Child ListView but It is not showing all my List values in same time which I had grabbed from Web service call.It showed first value only in list because the List View height was set to list's single item height.If I scroll down the Child ListView I am able to see all values in ListView.What I need is If i get five list values from Web service It has to show all five items in same time.
note: If I set hard coded values for List,It showed all items in Child ListView at one time.
Edited
How I achieved it using MergeAdapter
This createAdapter method would return Adapter object and I have set that Adapter into my Listview using setAdapter(createAdapter(new ArrayList<T>()))
private ListAdapter createAdapter(List<T> items) {
mergeAdapter = new MergeAdapter();
mergeAdapter.addAdapter(endlessFeedAdapter);
return mergeAdapter;
}
What I need is
I Have been suggested to use ExpandableListView instead of using two ListViews.
If I use ExpandableListView I will have to change the createAdapter method return type into ExpandableListAdapter for this I used below code
private ExpandableListAdapter createAdapter(List<T> items) {
mergeAdapter = new MergeAdapter();
mergeAdapter.addAdapter(endlessFeedAdapter);
return (ExpandableListAdapter) mergeAdapter;
}
but it showed the below Excaption
Caused by: java.lang.ClassCastException: com.commonsware.cwac.merge.MergeAdapter cannot be cast to android.widget.ExpandableListAdapter
Values from Web service
Hard coded values
What is stopping you to make 2 different adapters and adding them to MergeAdapter? You can add multiple adapters to MergeAdapter and multiple views. In that case there is no need to use 2 Listviews.
mergeAdapter.addAdapter(adapterHeading);
mergeAdapter.addView(someView);
mergeAdapter.addAdapter(adapterFooter);
listView.setAdapter(mergeAdapter);

Categories

Resources