I am trying to reinitialize the already set adapter for a spinner in android. I don't wanna create a new adapter object because the material spinner library i am using is having an issue when replacing already set adapter with a new object .
So I have a list that changes over time and once after I set the adapter to the spinner initially , afterwards when the list gets changed (updated , cleared etc) I want to reinitialize the already set adapter (using something like adapter.setList() whatever ) ...
I am new to android . Whats the best way to do this with minimal code ?
Try to call mAdapter.notifyDataSetChanged() after changing your adapter data (i.e. the list etc.). Without calling it, nothing will happen. Hope it helps.
Related
I'm making a file explorer synchronizing a directory in ftp, I would like that when a new item is downloaded it is displayed first in my recyclerview. For that I use sharedpreferences to store the new files and so I display or not a dot next to it to notify that it is new. Then I want to place it first at the begining of my MutableList, everything goes well except when I have to update with notifyItemMoved() which gives me the following error:
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView{e8a722f VFED..... ......ID 0,60-1536,1098 #7f080104 app:id/main_folder_recycle_view}, adapter:fr.frd.calvezdocs.adapter.DirAdapter#f17203c, layout:androidx.recyclerview.widget.GridLayoutManager#31331c5, context:fr.frd.calvezdocs.MainActivity#5181ba0
Here is the code in my onBindViewHolder() :
val isRead: String? = prefNewDir.getString(currentDir.absolutePath, null)
if (isRead!=null) {
holder.DirIsRead.visibility = View.VISIBLE
println("before : " + items[0])
items.remove(currentDir)
items.add(0,currentDir)
println("after : "+items[0])
// Can't update the recyclerview
notifyDataSetChanged()
} else
holder.DirIsRead.visibility = View.GONE
Does anyone have an idea?
Thanks
onBindViewHolder is the method the adapter calls when it's displaying the list, and it's passing you a ViewHolder so you can update it to display a particular item in the list.
It's not the place to be doing stuff like calculating that the list has changed, and requesting a new layout, which is why you're getting an exception. You also definitely shouldn't be changing the items dataset while the RecyclerView is trying to display part of it!
Really, your adapter should have some kind of setData function, where you pass in updated data, and it can do stuff like working out what's moved, sorting the list for display, keeping a list of what's new and needs a highlight dot, etc. And that function can call notifyDataSetChanged(), or one of the more specific (and better) update functions as appropriate.
When you get new data (e.g. when you're storing a new file in the SharedPreferences) that's when you should be pushing an update to the adapter, so it can do what it needs to do, and refresh if necessary. You can even make it a simple update() call that passes nothing, and the adapter does all the SharedPreferences lookup you're currently doing in onBindViewHolder, if you want. And it'll be a lot more efficient than doing these lookups every time an item in the list is drawn
(I'd really recommend against what you're doing with SharedPreferences too, but maybe it complicates things less than I'm imagining. I'd still recommend trying to make your adapter work with a basic list internally, though - pass one in, so it doesn't need to know how the rest of the app is persisting data)
I'd like to achieve the following behaviour:
When an spinner is touched it makes an http post that returns some results.
Until the results are received the spinner doesn't display showing its current results.
Once the results are received it finally displays showing the results.
I successfully manage to make the petition and getting the results problem is that it looks like when an spinner is touched it automatically displays. There seems to be no way of telling it: "I have now touched you, stop there, and when response is received then show the results that you have received."
Is there any way to do this?
Since every time user touch spinner you made a request, what you could do is , as user touch spinner , clear the values in adapter.
//Here is a list of options to use in spinner.
List<String> options;
ArrayAdapter<String> adapter = new ArrayAdapter<>(context , R.layout.simple_spinner_items , options);
as user touch the spinner clear adapter items or if you using custom Adapter implement clear functionality or if the custom adapter inherits ArrayAdapter then no need to implement clear functionality ,its already there.
adapter.clear();
once you received the data which is List of String (I'm assuming)
adapter.addAll(options);
I'm using the navigation drawer example in Android. What's the easiest way to change the string items in the adapter dynamically? Do I just create a new adapter and set it with my new values?
The problem is I'm altering the string items based on user state logged in and logged out. How do I access it from a non static context and just say update list adapter? It doesn't seem to be re-drawing itself and running my adapter code which is dynamic based on user state, so I guess it runs/inits once and I have to create and load a new adapter if I want to change it later?
Thanks.
You haven't given us much to go on (a little code would be nice), but you can update the data in the ListView by calling notifyDatasetChanged() on the Adapter. If you are not using a custom Adapter e.g. an ArrayAdapter then you can just create a new Adapter instance with different String values and set it to the ListView.
Ive got some gridView and some function which is called when a message arrives from server. In this function I get the values from server and I want to write this value in specific item in the gridView.
The problem is I dont have any idea how can I rewrite text of som Item in the gridView and I couldn find any answer on the internet :/
First you need to to add the received data into arraylist which you used to populate your grid view . You can add the received data into any position of arraylist as you need.
Then update the Arrayadapter using the following command
adapter.notifyDataSetChanged();
I understand up to some point. In my expatiation i think your set by using adapter right. So the simple solution is once you get the new items for a grid. call the setadapter again. Then that will set the new items. Try it once.
Actually i have to comment out but i don't have that much points.
I am trying to reload the list view when the data has changed. But its not working.Here is the code I am using
localPits.clear();//
this.adapter.clear();
//Fetch new data and update the list
this.localPits.addAll(pl);
this.adapter.notifyDataSetChanged();
this.lst_Pits.invalidate();
Each time I call this portion of code existing values are successfully removed. But new values are not loaded in the list view.
How can I do this in android?
Thanks
It's not terribly clear, but I suspect the new values aren't being loaded because you're clearing the adapter without updating it.
Your 2nd line: this.adapter.clear();
You need to update and add the adapter before you call invalidate(). Or, at least, that's as far as I can gather.
this.adapter.clear(); should not be needed. It must reset the links between adapter and localPits.
If you need to keep this, update list adapter localPits.setAdapter(adapter);. It should fix your problem.