'notifyDataSetChanged does not update my recycler view
I have a ArrayList getting data from IntentService. After I got my data I updated my adapter and called notifyDataSetChanged(). But it does not change data.
Here is my code:
public class Nearby_ViewPager_Stations extends Fragment {
private View mRootView = null;
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private StationsReceiver mStationsReciever;
private MKLoader mProgressBar;
private RecyclerView.Adapter mAdapter;
private Context mContext;
ArrayList<ArrayList<StationArrivalPOJO>> stationArrivalPOJO = new ArrayList<>();
private static final String TAG = "NearbyViewPagerStations";
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mRootView == null) {
mRootView = inflater.inflate(R.layout.nearby_viewpager_stations, container, false);
mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.recycler_view);
mProgressBar = (MKLoader) mRootView.findViewById(R.id.progressBar);
}
mStationsReciever = new StationsReceiver(new Handler());
mLayoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new Adapter_recyclerView(stationArrivalPOJO);
mRecyclerView.setAdapter(mAdapter);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
startIntentService();
handler.postDelayed(this, 20*1000);
}
}, 1000);
return mRootView;
}
private void startIntentService() {
Intent intent1 = new Intent(mContext, GetAllStationsAndStopsIntentService.class);
intent1.putExtra("Receiver", mStationsReciever);
intent1.putExtra("latitude", Constants.latitude);
intent1.putExtra("longitude", Constants.longitude);
mContext.startService(intent1);
}
void addAdapter(ArrayList<ArrayList<StationArrivalPOJO>> resultData) {
mProgressBar.setVisibility(View.GONE);
if (stationArrivalPOJO.size() > 0)
stationArrivalPOJO.clear();
stationArrivalPOJO.addAll(resultData);
mAdapter.notifyDataSetChanged();
Log.v(TAG, "added all data: "+ stationArrivalPOJO.get(0).get(0).getTimeToStation());
}
public class StationsReceiver extends ResultReceiver {
StationsReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
addAdapter((ArrayList<ArrayList<StationArrivalPOJO>>)resultData.getSerializable("StationPOJO"));
}
}
}
And here is my Adapter code:
class Adapter_recyclerView extends RecyclerView.Adapter {
private ArrayList<ArrayList<StationArrivalPOJO>> mStationPojoList;
private LinearLayout mLinearLayout;
private Context mContext;
private static final String TAG = "AdapterRecyclerView";
Adapter_recyclerView(ArrayList<ArrayList<StationArrivalPOJO>> data) {
mStationPojoList = data;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ViewHolder)holder).stationNameTV.setText(mStationPojoList.get(position).get(0).getStationName());
ArrayList<String> mUniqueStationName = new ArrayList<>(); //Unique platform names of a station got from hash set 'uniqStatNames'
HashSet<String> uniqStatNames = new HashSet<>(); //Unique platform names of a station
for (int i = 0;i<mStationPojoList.get(position).size(); i++) {
uniqStatNames.add(mStationPojoList.get(position).get(i).getPlatformName()
+ mStationPojoList.get(position).get(i).getTowards());
}
for(Iterator<String> it = uniqStatNames.iterator() ; it.hasNext() ; ) {
mUniqueStationName.add(it.next());
}
for (int j=0; j<mUniqueStationName.size(); j++) {
ArrayList<StationArrivalPOJO> arrivalPOJOs = new ArrayList<>(); //Platform wise categorized train details
for (int i = 0;i<mStationPojoList.get(position).size(); i++) {
if (mUniqueStationName.get(j).contains(mStationPojoList.get(position).get(i).getPlatformName())
&& mUniqueStationName.get(j).contains(mStationPojoList.get(position).get(i).getTowards())) {
arrivalPOJOs.add(mStationPojoList.get(position).get(i));
}
}
Collections.sort(arrivalPOJOs, new Comparator<StationArrivalPOJO>() {
@Override
public int compare(StationArrivalPOJO stationArrivalPOJO, StationArrivalPOJO t1) {
return stationArrivalPOJO.getTimeToStation() - t1.getTimeToStation();
}
});
for (int k=0; k<arrivalPOJOs.size(); k++) {
Log.v(TAG, j+":"+mUniqueStationName.size()+"boo"+arrivalPOJOs.toString());
Log.v(TAG, "boom " + arrivalPOJOs.get(k).getPlatformName() + ":" + arrivalPOJOs.get(k).getTowards());
RelativeLayout relativeLayout = new RelativeLayout(mContext);
relativeLayout.setPadding(16, 16, 16, 16);
LinearLayout linearLayout = new LinearLayout(mContext);
linearLayout.setOrientation(LinearLayout.VERTICAL);
TextView trainName = new TextView(mContext);
trainName.setText(arrivalPOJOs.get(k).getPlatformName());
TextView towards = new TextView(mContext);
towards.setText(arrivalPOJOs.get(k).getTowards());
linearLayout.addView(trainName);
linearLayout.addView(towards);
RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams1.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
linearLayout.setLayoutParams(layoutParams1);
TextView time = new TextView(mContext);
time.setText(String.valueOf(arrivalPOJOs.get(k).getTimeToStation()));
RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
time.setLayoutParams(layoutParams2);
relativeLayout.addView(linearLayout);
relativeLayout.addView(time);
mLinearLayout.addView(relativeLayout);
}}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rootView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.adapter_recyclerview,parent,false);
mContext = parent.getContext();
mLinearLayout = (LinearLayout) rootView.findViewById(R.id.cardViewLinearLayout);
TextView mStationName = (TextView) rootView.findViewById(R.id.stationName);
return new ViewHolder(rootView, mStationName);
}
@Override
public int getItemCount() {
return mStationPojoList.size();
}
private static class ViewHolder extends RecyclerView.ViewHolder {
TextView stationNameTV;
ViewHolder(View view, TextView stationNameTV) {
super(view);
this.stationNameTV = stationNameTV;
}
}
}
When I retrieve data from ArrayList and print in log station I get updated values. But that updates are not getting reflected in my recycler list.
I have seen other questions in Stack Overflow saying that:
we need update data from the same
FragmentobjectnotifyDataSetChanged()` should be called from ui thread.
I dont understand what I am missing.
Solution 1:[1]
TL;DR: Don't store your adapter in a property of your activity/fragment. Always call and cast from mRecyclerView.getAdapter()
I had the same issue.
All people only say is use notifyDataSetChanged() and that should do it (some might argue on using the notifyItem* ones, I'd say it depends)
Just fixed it thanks to your comments on the accepted answer (even when is not the correct one)
Yes, notifyDataSetChanged() is being called on my adapter, but is not the correct adapter to update.
I have a recycler with around 500 items being filtered, I can see that the new items list is being reduced to 10 items, but the UI was still showing all of the items.
This comment made me question if mine was being called, so I put some logs and well, I saw that it was still using the original 500 items list even after I got the logs that the adapter had a new list with just 10.
Well, this was caused by having a property in my fragment and updating that adapter.
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
onCreateView() {
// Retrieve data and more code
mRecyclerView = view.findViewById(R.id.recycler_view);
mAdapter = new MyRecyclerViewAdapter(data);
mRecyclerView.setAdapter(mAdapter);
}
filter(String txt) {
// Here the adapter handles filtering the list
// and calling notifyDataSetChanged()
mAdapter.filter(query);
}
Now it's like this and is working
private RecyclerView mRecyclerView;
onCreateView() {
// Retrieve data and more code
mRecyclerView = view.findViewById(R.id.recycler_view);
mRecyclerView.setAdapter(new MyRecyclerViewAdapter(data));
}
filter(String txt) {
// Here the adapter handles filtering the list
// and calling notifyDataSetChanged()
((MyRecyclerViewAdapter)mRecyclerView.getAdapter()).filter(query)
}
I'd say you don't have to accept an answer if it didn't help resolve your issue.
And if you solved it yourself you can answer your own question and accept your own answer.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Edgar Alvarado |
