2Real
2Real

Reputation: 4431

How to update a spinner dynamically?

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.

Upvotes: 38

Views: 68886

Answers (11)

Md Imran Choudhury
Md Imran Choudhury

Reputation: 9997

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)
    

Upvotes: 0

Fifer Sheep
Fifer Sheep

Reputation: 2990

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()

Upvotes: 33

no-name
no-name

Reputation: 477

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()

Upvotes: 3

Dharmendra
Dharmendra

Reputation: 33996

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.

Upvotes: 11

loshkin
loshkin

Reputation: 1630

When you set up the spinner adapter add

spinnerAdapter.setNotifyOnChange(true);

From then on when you add new data it will be automatically updated.

Upvotes: 1

kgao
kgao

Reputation: 11

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());

Upvotes: 1

AdamC
AdamC

Reputation: 16273

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);

Upvotes: 32

codingForFun
codingForFun

Reputation: 123

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);

Upvotes: 2

Kapil D
Kapil D

Reputation: 2660

Change the underlying data and call the notifyDataSetChanged() on adapter.

   list.clear();
  list.add("A");
      list.add("B");
  dataAdapter.notifyDataSetChanged();

Upvotes: 2

Robby Pond
Robby Pond

Reputation: 73484

You only need to call setAdapter() once and you call adapter.notifyDataSetChanged() to update the data.

Upvotes: 13

Cristian
Cristian

Reputation: 200080

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();

Upvotes: 4

Related Questions