I'm trying to populate a listView, but if I initialize it after onCreate it doesn't appear. I tried to initialize it into the onCreate and use adapter.notifyDataSetChanged(); after I insert values into my String array used to populate the listView but I have no success.
Does someone know how to solve this problem? I checked other questions but I didn't find an answer to my problem.
Thanks in advance.
Maybe you need to call adapter.notifyDataSetChanged() inside the UI thread.
Also it's better to use an ArrayList<String> instead of a String[]
Keep references to both the ArrayList and ArrayAdapter inside your activity class.
private ArrayList<String> items;
private ArrayAdapter<String> adapter;
Initialize your ArrayList<String> and set adapter in your onCreate
items = new ArrayList<String>();
// add initial items
items.add("1st item");
// create adapter
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
// set the adapter
listView.setAdapter(adapter);
Now whenever you want to change the items, call the add(), remove(), etc methods of the ArrayList and subsequently call adapter.notifyDataSetChanged(). The change to the ArrayList can be done in any thread, but adapter.notifyDataSetChanged() should be called in UI thread.
For example in a button press you might wanna do
items.add("New item");
adapter.notifyDataSetChanged();
Also you might wanna check these:
this and
this
PS: Sorry for my bad posting skills. I'm new.
Related
This must be a simple question, as I am new to Android.
I have a implementation of a ListAdapter but need to update the list when changes are made to the objects list that runs it. It is suggested in various posts to use notifyDataSetChanged(). However naturally I get the error 'cannot find method':
ListView lv = (ListView) findViewById(R.id.menu_list_activity);
((ListAdapter) lv.getAdapter()).notifyDataSetChanged();
In the onCreate() of the Activity I added it to the ListView:
lv.setAdapter(new MenuListAdapter(this, objects));
As the ListAdapter is only an interface. The method however is included in the ArrayAdaptor.
So what should I use, what is the best way? I basically just have a List with objects to be used to populate the ListView.
You could also do following
MenuListAdapter menuListAdapter = new MenuListAdapter(this, objects)
lv.setAdapter(menuListAdapter);
Now just call following anywhere.
menuListAdapter.notifyDataSetChanged();
As #laalto mentioned you must be extending right Adapter in your custom adapter class. Either BaseAdapter directly or any of the adapters that expend Base Adapter like ArrayAdapter.
In the adapters inheritance tree, notifyDataSetChanged() is defined in BaseAdapter. Assuming your MenuListAdapter extends BaseAdapter directly or indirectly, cast the result of getAdapter() to BaseAdapter to invoke the method.
While creating the adapter store it into a local variable and then use that variable.
MenuListAdapter adapter = new MenuListAdapter(this, objects)
lv.setAdapter(adapter);
// You need to update the objects list, so that adapter can get the recent update
objects.add(newItem);
// Then notify the adapter
adapter.notifyDataSetChanged();
I used notifyDataSetChanged for adapter but my List didn't updated. Here is part of my code.
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,userNames);
list = (ListView) findViewById(R.id.listViewUsers);
list.setAdapter(adapter);
SO every time I'm adding item to userNames , I'm calling adapter.notifyDataSetChanged(); method, but there are no any updates. I tried many things with cleaning , clearing userNames but it's not working.
Can anyone help me?
Thanks
EDIT:
I'm calling these two functions where I'm adding new user.
userNames.add(user.getUsername());
adapter.notifyDataSetChanged();
Also I have User class, but I fill in ListView with users' usernames.
Try add username directly to adapter instead of adding to userNames. Maybe when you create a new instance of ArrayAdapter, it will create a new private List inside adapter and you add username to old instance of userNames :
adapter.add(user.getUsername());
adapter.notifyDataSetChanged();
For an ArrayAdapter, notifyDataSetChanged() only works if you use the add, insert, remove, and clear functions on the Adapter.
When an ArrayAdapter is constructed, it holds the reference for the List that was passed in. If you were to pass in a List that was a member of an Activity, and change that Activity member later, the ArrayAdapter is still holding a reference to the original List. The Adapter does not know that you changed the List in the Activity.
Try this:
userNames.add(user.getUsername());
adapter.clear();
adapter.addAll(userNames);
adapter.notifyDataSetChanged();
I have a ListAdapter as shown below:
setListAdapter(new ArrayAdapter<String>(DeleteMenu.this,
android.R.layout.simple_list_item_1,
classes));
I am trying to call notifyDataSetChanged() on it within an onListItemClick() function. I've tried a few different ways and looked at similar questions here on StackOverFlow but I still can't figure it out.
Can someone please help?
Edit: I should be more clear, I'm not getting an error, I simply don't know what to call the function notifyDataSetChanged() method on. Do I have to assign my ListAdapter to a variable and call it like var.notifyDataSetChanged()?
You should call notifyDataSetChanged on Adapter.
Adapter adapter = new Adapter();
ListView list = (ListView) findViewById(R.id.listview);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
You can call the method notifyAdapterChanged() by getting a reference to the Adapter. You can either keep a local reference (like user1411084s answer), or retrieve it by calling:
getListAdapter()
Important to notice is that the interface ListAdapter doesn't provide the method notifyDataSetChanged(), so you should cast it to the type of the adapter you assigned earlier.
The result will look like this (able to call anywhere in your ListActivity/ListFragment:
((ArrayAdapter) getListAdapter()).notifyDataSetChanged();
((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
See more info in this answer:
https://stackoverflow.com/a/4198569/3994630
Consider the following code.
List<String> list = new ArrayList<String>();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, resource, textViewResourceId, list);
// Method 1 : Add an item.
adapter.add("ITEM1");
// Method 2 : Add an item
list.add("ITEM2");
I was wondering, which is the correct way to add item into ArrayAdapter? As seems to me, both methods just work fine.
Method 1 updates the associated AdapterView, if you have already attached the ArrayAdapter to the AdapterView. Method 2 does not, requiring you to call notifyDataSetChanged() on the ArrayAdapter.
Typically, you populate the ArrayList before creating the ArrayAdapter, then use Method 1 to add new entries dynamically later on (e.g., based on user data entry).
This is what I do, especially for my Search Results page - where it grows as the user scroll down (list changes).
I'd keep a local ArrayList of Strings that is global to the class,
Initialize the adapter (also locally and globally),
Have a designated method alter the ArrayList of strings,
Then call the adapter.notifyDataSetChanged();
This will not only update your list and also update the adapter to work in sync.
Hope this helps,
best,
-serkan
I've been trying to update my spinner in android dynamically but nothing I try has been working.
This is the following code I'm using to update the spinner.
typeList = dbAdapter.getList(); //array list with the values
adapter.notifyDataSetChanged();
groupSpinner.postInvalidate();
groupSpinner.setAdapter(adapter);
The values of typeList are correct but they're not being updated in the Spinner.
Actually, you either have to call clear/add on the adapter, or create and set a new adapter. The adapter does not retain a reference to your list (it is only calling toArray on your list at construction), so there is no way for it to update itself.
dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, newStringList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerCategory.setAdapter(dataAdapter);
You can't directly modify the original List then call notifyDataSetChanged() like on other adapters, as it doesn't hold on to the original List.
You can, however, achieve the same result using the adapter itself, like so:
spinnerAdapter.clear();
spinnerAdapter.addAll(updatedListData);
spinnerAdapter.notifyDataSetChanged(); // optional, as the dataset change should trigger this by default
Based on this answer from user392117.
edit: By default, methods that change the list like add() and remove() automatically call notifyDataSetChanged() (see Android Developer Documentation for setNotifyOnChange(boolean) )
public void setNotifyOnChange (boolean notifyOnChange)
Control whether methods that change the list (add, addAll(java.util.Collection), addAll(java.lang.Object[]), insert, remove, clear, sort(java.util.Comparator)) automatically call notifyDataSetChanged. If set to false, caller must manually call notifyDataSetChanged() to have the changes reflected in the attached view. The default is true, and calling notifyDataSetChanged() resets the flag to true.
So you should not need to call notifyDataSetChanged() every time. If you find that this is the case, you can use setNotifyOnChange(true)
spinnerAdapter.setNotifyOnChange(true); //only need to call this once
spinnerAdapter.add(Object); //no need to call notifyDataSetChanged()
You only need to call setAdapter() once and you call adapter.notifyDataSetChanged() to update the data.
When you have data changed in your list and when you want to update
the spinner then
Create a new object of the adapter and set that adapter to the
spinner. It will work sure.
Best of luck.
Edit: Also you need to call notifyDataSetChanged() on the adapter.
Is there a typo or something? Which is the difference between dbAdapter and adapter. If the Spinner has already the adapter, you don't have to re-assign it. More over, the only think you have to do is update the adapter and call notifyDataSetChanged method.
typeList = adapter.getList(); //array list with the values
// change the values, and then
adapter.notifyDataSetChanged();
Using add/remove on your adapter and using notifyDataSetChanged() enables you not having to create new adapters over and over again.
Declare your adapter global
ArrayAdapter<Object> adapter;
When you add something to the List of Objects the adapter is attached to (Strings or whatever object you use) add an add function to the adapter and call notifyDataSetChanged:
adaper.add(Object);
adapter.notifyDataSetChanged();
and when you remove an item from the List add also:
adapter.remove(Object);
adapter.notifyDataSetChanged();
edit: By default, methods that change the list like add() and remove() automatically call notifyDataSetChanged() (see Android Developer Documentation for setNotifyOnChange(boolean) )
public void setNotifyOnChange (boolean notifyOnChange)
Control whether methods that change the list (add, addAll(java.util.Collection), addAll(java.lang.Object[]), insert, remove, clear, sort(java.util.Comparator)) automatically call notifyDataSetChanged. If set to false, caller must manually call notifyDataSetChanged() to have the changes reflected in the attached view. The default is true, and calling notifyDataSetChanged() resets the flag to true.
So you should not need to call notifyDataSetChanged() every time. If you find that this is the case you you can use setNotifyOnChange(true)
adapter.setNotifyOnChange(true); //only need to call this once
adapter.add(Object); //no need to call notifyDataSetChanged()
Change the underlying data and call the notifyDataSetChanged() on adapter.
list.clear();
list.add("A");
list.add("B");
dataAdapter.notifyDataSetChanged();
After you change your data, you will need to add the following code:
typeList = dbAdapter.getList()
adapter = new ArrayAdapter<String>(v.getContext(),
android.R.layout.simple_spinner_dropdown_item,typeList);
groupSpinner.setAdapter(adapter);
Apparently after you do typeList = dbAdapter.getList(), the variable typeList points to a different List rather than the one you fed to the adapter originally and the adapter would be somewhat confused.
So you should use the following code:
typeList.clear();
typeList.addAll(dbAdapter.getList());
When you set up the spinner adapter add
spinnerAdapter.setNotifyOnChange(true);
From then on when you add new data it will be automatically updated.
First of all, you have to initialize the adapter with ArrayList<T>. Otherwise, you might get an exception.
val list: ArrayList<String> = arrayListOf()
private lateinit var spinnerAdapter: ArrayAdapter<String>
After that initialize the adapter:
spinnerAdapter = ArrayAdapter<String>(requireContext(),
android.R.layout.simple_spinner_item,
list) // initialize with empty arrayList
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.spinnerCurrency.apply {
adapter = spinnerAdapter
}
After that when you have data clear and add all list.
spinnerAdapter.clear()
spinnerAdapter.addAll(list)