Ayush Chauhan Ayush Chauhan - 4 months ago 16
Java Question

RecyclerView Adapter not able to delete all elements

I am not able to find the working solution for this problem and i dont know how to phrase the problem correctly.I am using OpenWeather API to get forecast for next seven days.I have defined a separate class for all the network related work and storing the result in sqlite database and then attaching the result string to recycler view.I have used retrofit to turn my HTTP API into a Java interface.I have passed the recycler view adapter to this class constructor from my MainFragment class.I am able to correctly get data from the api but the following code is not working properly

@Override
public void onResponse(Call<OpenWeather> call, Response<OpenWeather> response) {
int code = response.code();
if (code == 200) {
OpenWeather openWeather = response.body();
String []result = getWeatherDataFromRetrofit(openWeather,postal);
if (mForecastAdapter != null) {
Log.e(LOG_TAG,""+mForecastAdapter.getItemCount());
for(int i=0;i<mForecastAdapter.getItemCount();i++){
mForecastAdapter.remove(i);
}
for(int i=0;i<result.length;i++) {
String dayForecastStr = result[i];
mForecastAdapter.add(i,dayForecastStr);
}
// New data is back from the server. Hooray!

}

} else {
Toast.makeText(mContext, "Did not work: " + String.valueOf(code), Toast.LENGTH_LONG).show();
}
}


This function is asynchronously called in retrofit.The for loop which is used for removing elements in mForecastAdapter is not running completely which is causing the list to contain the duplicate item

Heres the remove and add function i used Recycler View adapter

public void add(int position, String item) {
mDataset.add(position, item);
Log.e("Add element:", item);
notifyItemInserted(position);
}

public void remove(int position) {
Log.e("Remove element:",mDataset.get(position));
mDataset.remove(position);
notifyItemRemoved(position);
}


Following is the Log entry which is showing that the for loop i am using for clearing the mForecastAdapter is not running completely

When App starts

E/FetchWeatherTask: 0
E/Add element:: Sun, Jul 10 - Rain - 35/27
E/Add element:: Mon, Jul 11 - Rain - 32/27
E/Add element:: Tue, Jul 12 - Rain - 32/27
E/Add element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Thu, Jul 14 - Rain - 32/26
E/Add element:: Fri, Jul 15 - Rain - 33/27
E/Add element:: Sat, Jul 16 - Rain - 32/27


When i refresh the app for first time

E/FetchWeatherTask: 7
E/Remove element:: Sun, Jul 10 - Rain - 35/27
E/Remove element:: Tue, Jul 12 - Rain - 32/27
E/Remove element:: Thu, Jul 14 - Rain - 32/26
E/Remove element:: Sat, Jul 16 - Rain - 32/27
E/Add element:: Sun, Jul 10 - Rain - 35/27
E/Add element:: Mon, Jul 11 - Rain - 32/27
E/Add element:: Tue, Jul 12 - Rain - 32/27
E/Add element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Thu, Jul 14 - Rain - 32/26
E/Add element:: Fri, Jul 15 - Rain - 33/27
E/Add element:: Sat, Jul 16 - Rain - 32/27


When i refreshed the app for second time

E/FetchWeatherTask: 10
E/Remove element:: Sun, Jul 10 - Rain - 35/27
E/Remove element:: Tue, Jul 12 - Rain - 32/27
E/Remove element:: Thu, Jul 14 - Rain - 32/26
E/Remove element:: Sat, Jul 16 - Rain - 32/27
E/Remove element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Sun, Jul 10 - Rain - 35/27
E/Add element:: Mon, Jul 11 - Rain - 32/27
E/Add element:: Tue, Jul 12 - Rain - 32/27
E/Add element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Thu, Jul 14 - Rain - 32/26
E/Add element:: Fri, Jul 15 - Rain - 33/27
E/Add element:: Sat, Jul 16 - Rain - 32/27


I am not able to understand why the for loop used for removing element is not working correctly.Thanks in advanced

Solution :-

int count = mForecastAdapter.getItemCount()
for(int i=0;i<count;i++){
mForecastAdapter.remove(i);
}


Or I can clear the list in one go in the remove()

public void remove() {
mDataset.clear();
notifyItemRemoved(position);
}

Answer

Your problem is here:

for(int i=0;i<mForecastAdapter.getItemCount();i++){
    mForecastAdapter.remove(i);
}

Basically, mForecastAdapter.getItemCount() returns a different size every iteration of your for loop since you are removing items and changing its size. That means that for 10 items, you are both incrementing i and decrementing your count effectively running your loop half as many times as you'd like.

Second problem: you are deleting the ith item every iteration, but lists in Java re-index when you remove items.

Try this:

int count = mForecastAdapter.getItemCount();
for (int i = 0; i < count; ++i) {
    mForecastAdapter.remove(0);
}
Comments