ListView doesn't refresh on notifyDataSetChanged - android

ListView doesn't seem to refresh when notifyDataSetChanged(); is called, but does refresh when its adapter gets set again.
In my Activity onCreate I initialize my ListView and my adapter. Then I have this Hanler that checks for new values every second. listview.setAdapter(arrayAdapter); works but arrayAdapter.notifyDataSetChanged(); doesn't do anything.
Here is the code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.listView1);
arrayAdapter = new ArrayAdapter<Integer>(this,android.R.layout. simple_list_item_1, myIntegers);
lv.setAdapter(arrayAdapter);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (msg.what == DIS){
handler.sendEmptyMessageDelayed(DIS, 1000);
if(!refresh()){
handler.removeMessages(DIS);
}
}
}
};
public boolean refresh(){
if(ports.isEmpty()){
return false;
}else{
listview.setAdapter(arrayAdapter); //WORKS
arrayAdapter.notifyDataSetChanged(); // DOESN'T WORK
return true;
}
}
So I was wondering how to make that work with notifyDataSetChanged, because I read that it is the right way to do it, and anyway even if the setAdapter does work it makes my listview jump to beginning every time it refreshes it.
EDIT:
To clarify things, I am adding more values to myIntegers.

Try instead adding the values using the adapter.add() method. I dont think you can modify the array that was used to create the adapter and then expect it to hold an updated instance to update the views from. Best of Luck!

Related

How ArrayAdapter really works with ListView?

I'm confused how the actually ArrayAdapter works? As I was testing with ArrayAdapter and read about it that I have to call the notifyDataSetChanged(); on adapter or update the listView's adapter (as listView.setAdapter()) to update the record in ListView.
Now check this code.
public class MainActivity extends AppCompatActivity {
ArrayList<String> list = new ArrayList<>();
ExampleArrayAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView)findViewById(R.id.listView);
adapter = new ExampleArrayAdapter(this,list);
listView.setAdapter(adapter);
// Here I'm adding record after the listView.setAdapter(adapter);
// it is working fine.
list.add("Good");
list.add("Bad");
}
public void addData(View view){
// but when I call this method from Button then it doesn't working.
list.add("New Data Added");
}
}
I don't think so there is any difference between these lines.
list.add("Good");
list.add("Bad");
and
list.add("New Data Added");
Both are adding record after the setAdapter();
Then why list.add("New Data Added"); is not working.
After onCreate() by activity lifecycle run onStart() and onResume(). draw is after onCreate(). Therefore 2 items are visible.
addData(View view) runs after view is visible. To refresh values you need at this place adapter.notifyDataSetChanged();

ArrayAdapter and ListView never updating

I'm attempting to get method to handle updates to the ListView when SetWeatherData is called. Nothing ever shows up in my listview below. Any ideas? _rootView points to the right root and ListView comes back not null. m_weatherdata has a couple string elements in it.
Note the initial set of data does not show up either. Just blank.
I'm thinking it should be easier to setup a generic method to update a ListView when the data changes using straight up code.
private ArrayList<String> m_weatherdata;
private void SetWeatherData ( ArrayList<String> _weather)
{
m_weatherdata = _weather;
UpdateWeatherUI();
return;
}
ArrayAdapter<String> m_adapter = null;
private void UpdateWeatherUI()
{
if ( m_adapter == null ) {
m_adapter = new ArrayAdapter<String>(
this.getContext(),
R.layout.list_item_forecast,
R.id.list_item_forecast_textview,
m_weatherdata);
View _rootview = this.getLayoutInflater(null).inflate(R.layout.fragment_main, null, false);
ListView _listview = (ListView) _rootview.findViewById(R.id.listview_forecast);
_listview.setAdapter(m_adapter);
}
else
{
m_adapter.notifyDataSetChanged();
}
}
You are assigning a new ArrayList to your dataset.
m_weatherdata = _weather;
Instead add items to the dataset. Like this
m_weatherdata.addAll(_weather);
private void SetWeatherData ( ArrayList<String> _weather)
{
m_weatherdata.addAll(_weather);//change here
UpdateWeatherUI();
return;
}
When you set an adapter there is an observer attached to the
underlying data. So notifyDatasetChanged() only works if you only
modify the data in it.
If you want to clear all data from your dataset before adding new items to it, use the clear() method of ArrayList
private void SetWeatherData ( ArrayList<String> _weather)
{
m_weatherdata.clear();//change here
m_weatherdata.addAll(_weather);//change here
UpdateWeatherUI();
return;
}
m_weatherdata = _weather; // updates the local variable with new set of data. but adapter doesn't know about the changes made as you have created the instance of the adapter with array list by the following line of code.
m_adapter = new ArrayAdapter<String>(this.getContext(), R.layout.list_item_forecast,R.id.list_item_forecast_textview,m_weatherdata);
In you want to updated the data either call
m_adapter.addAll(newsetofstringtobeadded);
or
Create new adapter
This will update your list.

Remove all items from RecyclerView

I am trying to remove all the elements from my RecyclerView in my onRestart method so the items don't get loaded twice:
#Override
protected void onRestart() {
super.onRestart();
// first clear the recycler view so items are not populated twice
for (int i = 0; i < recyclerAdapter.getSize(); i++) {
recyclerAdapter.delete(i);
}
// then reload the data
PostCall doPostCall = new PostCall(); // my AsyncTask...
doPostCall.execute();
}
But for some reason the delete method I created in the adapter is not functioning properly:
in RecyclerAdapter.java:
public void delete(int position){
myList.remove(position);
notifyItemRemoved(position);
}
public int getSize(){
return myList.size();
}
I think every other item in my list gets deleted instead of the entire list.
With a listview it was so easy and I simply called adapter.clear().
Can someone please help me fix up the code?
I think I should be using notifyItemRangeRemoved(...,...); but I am not sure how. TIA
This works great for me:
public void clear() {
int size = data.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
data.remove(0);
}
notifyItemRangeRemoved(0, size);
}
}
Source: https://github.com/mikepenz/LollipopShowcase/blob/master/app/src/main/java/com/mikepenz/lollipopshowcase/adapter/ApplicationAdapter.java
or:
public void clear() {
int size = data.size();
data.clear();
notifyItemRangeRemoved(0, size);
}
For you:
#Override
protected void onRestart() {
super.onRestart();
// first clear the recycler view so items are not populated twice
recyclerAdapter.clear();
// then reload the data
PostCall doPostCall = new PostCall(); // my AsyncTask...
doPostCall.execute();
}
Avoid deleting your items in a for loop and calling notifyDataSetChanged in every iteration. Instead just call the clear method in your list myList.clear(); and then notify your adapter
public void clearData() {
myList.clear(); // clear list
mAdapter.notifyDataSetChanged(); // let your adapter know about the changes and reload view.
}
setAdapter(null);
Useful if RecycleView have different views type
recyclerView.removeAllViewsInLayout();
The above line would help you remove all views from the layout.
For you:
#Override
protected void onRestart() {
super.onRestart();
recyclerView.removeAllViewsInLayout(); //removes all the views
//then reload the data
PostCall doPostCall = new PostCall(); //my AsyncTask...
doPostCall.execute();
}
This is how I cleared my recyclerview and added new items to it with animation:
mList.clear();
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
//reset adapter with empty array list (it did the trick animation)
mAdapter = new MyAdapter(context, mList);
recyclerView.setAdapter(mAdapter);
mList.addAll(newList);
mAdapter.notifyDataSetChanged();
Help yourself:
public void clearAdapter() {
arrayNull.clear();
notifyDataSetChanged();
}
I use this. This actually clears the recylerview completely. I had tried adapter.notifyDataSetChanged(); but it was just not updating any view in my case. Of course U had cleared the list first. But below code works fine and clears view of recyclerview completely.
listName.clear(); // clear list
adapter = new ModelAdaptor(Activity.this, listName);
recyclerView.setAdapter(adapter);
Another way to clear the recycleview items is to instanciate a new empty adapter.
mRecyclerView.setAdapter(new MyAdapter(this, new ArrayList<MyDataSet>()));
It's probably not the most optimized solution but it's working like a charm.
ListView uses clear().
But, if you're just doing it for RecyclerView. First you have to clear your RecyclerView.Adapter with notifyItemRangeRemoved(0,size)
Then, only you recyclerView.removeAllViewsInLayout().
For my case adding an empty list did the job.
List<Object> data = new ArrayList<>();
adapter.setData(data);
adapter.notifyDataSetChanged();
private void clearRecyclerView() {
CustomListViewValuesArr.clear();
customRecyclerViewAdapter.notifyDataSetChanged();
}
use this func
On Xamarin.Android, It works for me and need change layout
var layout = recyclerView.GetLayoutManager() as GridLayoutManager;
layout.SpanCount = GetItemPerRow(Context);
recyclerView.SetAdapter(null);
recyclerView.SetAdapter(adapter); //reset
You have better clear the array-list that you used for recyleview adapter.
arraylist.clear();
public void clearData() {
mylist.removeAll(mylist);
mAdapter.notifyDataSetChanged();
recyclerView.setAdapter(mAdapter);
}

Refresh listview onpost execute asynctask

i know this question has been posted multiple times and i browsed almost all of them but there is not result, i am performing a deleting an item from mysql database but it is not refreshing, here is the code of the onclicklistener and the button:
onClick listener:
holder.void_button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
adapter = new CustomListViewVoidAdapter(context,R.layout.mytemp, items);
item_selected= items.get(position);
new DeleteOrder().execute();
}});
vi.setTag(holder);
}
OnPostExecute from AsyncTask:
protected void onPostExecute(String unused){
adapter.remove(item_selected);
adapter.notifyDataSetChanged();
}
the adapter is instatiated globally, can you please check where the problem might be?
it is not returning any error, just deleting the item and not refreshing.
Regards
Ralph
Throwing it out there, but, have you tried adapter.notifyDataSetInvalidated();? That forces an update.
Also, put the code in the asynctask!
Like such:
protected void onPostExecute() {
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
}
You better set the adapter again to the list view in onPostExecute with the new values. And you don't need to call notifyDataSetChangedin this case. Also don't re-intialize the adapter in onClick, this is not neccessary.
Add below line in postExecute.
if(adapter != null) {
adapter = new CustomListViewVoidAdapter(context,R.layout.mytemp, items);
YourListviewObject.setAdapter(adapter);
}

android refresh listview adapter within getview()

I have got a custom list view adapter and an image button in the adapter class. When i click on the image button, the listener should reload the list view. I need to reload the list view within getview() of adapter class. So I need to know other options than using notifyDataSetChanged() in my listActivity class.
Thanks
You want to refresh a cell inside the listview or do you want to refresh the whole listview, if a single row is loaded inside getView() ?
Check this out:
Android ListView Refresh Single Row
Create a static handler inside the activity which calls a method which reloads the listview and send a message to this handler from the adapter whenever required.
handler = new Handler() {
public void handleMessage(Message paramAnonymousMessage) {
switch (paramAnonymousMessage.what) {
case 1:
populateList();
break;
}
}
};
public void populateBill() {
MyBasketAdapter adapter = new MyBasketAdapter(this, basketList);
listView = (ListView) findViewById(android.R.id.list);
listView.setAdapter(adapter);
}
Inside the adapter class. for example,
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Message msg = Message.obtain();
msg.what = 1;
MyActivity.handler.sendMessage(msg);
}
});
That is very Simple just write a method in your adapter class and call it get view when you deleting or adding anything in your list which you are binding to your adapter.and use notifyDataSetChanged after change in list
public void updateResults(ArrayList<CustomList> results) {
// assign the new result list to your existing list it will work
notifyDataSetChanged();
}

Categories

Resources