RecyclerView is not updated after NotifyDataSetChanged (), the content is displayed after turning the screen on and off.

I am new to Android and I am creating an application and a group of college friends. The problem that we encountered is that when filling out the list of elements displayed when receiving data from the server, the data is loaded and added to the list, but recyclerView never displays it (even after calling NotifyDataSetChanged from my user adapter). Back when we used hard-coded data to test an application, this never happened.

The strange part is that the list of items will be displayed in recyclerView after I turn off the display and then bring it back (the onBindViewHolder of my custom adapter is called when I turn on the screen again). Moreover, if I replace the fragment containing the recyclerView with another, and then return it, the data will be loaded into the list, but not shown.

What I want to know is why this happens, and what I can do to solve it (and, by solving this, I mean to show that the recyclerView is filled with the correct elements when I run the fragment and update the recyclerView when I add more elements to the list)

We use custom adpater and Retrofit to receive data from the server.

Here is the code

Snippet containing recyclerView

public class EventViewListFragment extends Fragment implements EventListAdapter.ClickListener{ private RestClient restClient; private Builder builder; private String token ; private boolean userScrolled = true; int pastVisiblesItems, visibleItemCount, totalItemCount; private LinearLayoutManager mLayoutManager; private RecyclerView recyclerView; private EventListAdapter eventListAdapter; private Button btnNewEvent; FloatingActionButton suggestFAB; private int currentPage=1; public EventViewListFragment(){ restClient = new RestClient(); } @Override public void onCreate(Bundle savedInstanceState) { System.out.println("Se llamo al onCreate de EventViewListFragment"); super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { System.out.println("se llamo al onCreateView de EvENT List Fragment"); // Inflate the layout for this fragment View layout =inflater.inflate(R.layout.fragment_events_list, container, false); setUpElements(layout); addListeners(); return layout; } private void setUpElements(View layout) { recyclerView = (RecyclerView) layout.findViewById(R.id.eventList); eventListAdapter = new EventListAdapter(getActivity()); eventListAdapter.setClickListener(this); eventListAdapter.setData(getInitialData()); recyclerView.setAdapter(eventListAdapter); mLayoutManager=new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(mLayoutManager); suggestFAB = (FloatingActionButton) layout.findViewById(R.id.suggestFAB); builder = new Builder(); } private void addListeners() { addNewEventListener(); addScrollBottomListener(); } private void addNewEventListener() { /*btnNewEvent.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view) { EventsActivity.getInstance().toNewEventForm(); } });*/ suggestFAB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { EventsActivity.getInstance().toNewEventForm(); currentPage=1; } }); } public List<Event> getInitialData() { List<Event> data=new ArrayList<>(); data = getEvents(data); return data; } @Override public void itemClicked(View view, int position) { EventsActivity.getInstance().toEventPage(eventListAdapter.getItemAtPos(position)); currentPage=1; } private void addScrollBottomListener() { recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { userScrolled = true; } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); // Here get the child count, item count and visibleitems // from layout manager visibleItemCount = mLayoutManager.getChildCount(); totalItemCount = mLayoutManager.getItemCount(); pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition(); if (userScrolled && (visibleItemCount + pastVisiblesItems) == totalItemCount) { userScrolled = false; addNewElementsToList(); } } }); } private void addNewElementsToList() { Toast.makeText(getActivity(), "Cargando Mas Elementos", Toast.LENGTH_SHORT).show(); eventListAdapter.setData(getEvents(eventListAdapter.getData())); } private List<Event> getEvents(final List<Event> eventsList) { System.out.println("Asignando CALL"); Call<JsonElement> eventPage = restClient.getConsumerService().getEvents(token, "", currentPage, 10); System.out.println("Enquequeing"); eventPage.enqueue(new Callback<JsonElement>() { @Override public void onResponse(Response<JsonElement> response) { JsonObject responseBody = response.body().getAsJsonObject(); if (responseBody.has("events")) { JsonArray jsonArray = responseBody.getAsJsonArray("events"); System.out.println(jsonArray.size()); for (int i = 0; i < jsonArray.size(); i++) { JsonObject storedObject = jsonArray.get(i).getAsJsonObject(); Event current = new Event(); current.setEventId(storedObject.get("id").getAsInt()); current.setName(storedObject.get("title").getAsString()); Calendar startCal = new GregorianCalendar(); startCal.setTimeInMillis((storedObject.get("starts_at").getAsLong()) * 1000); current.setStartDateTime(startCal); Calendar endCal = new GregorianCalendar(); endCal.setTimeInMillis((storedObject.get("ends_at").getAsLong()) * 1000); current.setFinishDateTime(endCal); current.setImgUrl(storedObject.get("image").getAsString()); eventsList.add(current); } } else { if (responseBody.has("error")) { System.out.println("ERROR"); wan.wanmarcos.models.Error error = builder.buildError(responseBody.get("error").getAsJsonObject()); Toast.makeText(getActivity(), "Error : " + error.toString(), Toast.LENGTH_SHORT).show(); } else { } } } @Override public void onFailure(Throwable t) { } }); eventListAdapter.notifyDataSetChanged(); currentPage++; return eventsList; } } 

Custom adapter for RecyclerView

  public class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.EventListViewHolder>{ private LayoutInflater inflater; private List<Event> data = Collections.emptyList(); private Context context; private ClickListener clickListener; public EventListAdapter(Context context){ inflater = LayoutInflater.from(context); this.context=context; } @Override public EventListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.event_list_item, parent, false); EventListViewHolder holder = new EventListViewHolder(view); return holder; } @Override public void onBindViewHolder(EventListViewHolder holder, int position) { System.out.println("se llamo al onBindViewHolder de ELA"); Event current = getData().get(position); holder.title.setText(current.getName()); Picasso.with(context) .load(current.getImgUrl()) .into(holder.img); String startDateAndTime = current.CalendarToString(current.getStartDateTime())+" - "+current.CalendarToString(current.getFinishDateTime()); holder.dateAndTime.setText(startDateAndTime); } public void setClickListener(ClickListener clickListener){ this.clickListener=clickListener; } @Override public int getItemCount() { return getData().size(); } public List<Event> getData() { return data; } public void setData(List<Event> data) { this.data = data; } class EventListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { TextView title; TextView dateAndTime; ImageView img; public EventListViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); title = (TextView) itemView.findViewById(R.id.eventListTitle); img = (ImageView) itemView.findViewById(R.id.eventListImage); dateAndTime =(TextView) itemView.findViewById(R.id.eventListDateAndTime); } @Override public void onClick(View v) { if(clickListener!=null) { clickListener.itemClicked(v,getPosition()); } } } public Event getItemAtPos(int pos) { return getData().get(pos); } public interface ClickListener{ public void itemClicked(View view,int position); } } 

Fragment XML File

  <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout android:id="@+id/main_content" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="wan.wanmarcos.fragments.EventViewListFragment"> <android.support.v7.widget.RecyclerView android:id="@+id/eventList" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" > </android.support.v7.widget.RecyclerView> </RelativeLayout> <android.support.design.widget.FloatingActionButton android:id="@+id/suggestFAB" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|right" app:layout_anchorGravity="bottom|right|end" android:layout_margin="16dp" android:clickable="true" android:src="@mipmap/ic_add_white_48dp" /> </android.support.design.widget.CoordinatorLayout> 
+5
source share
1 answer

eventsList in your Activity and data in your adapter are two different collections. You fill in the first, not the last. Intialize data with new ArrayList<> instead of Collections.emptyList(); , and then add the method to your adapter, call addAll, for example:

 public void addAll(final List<Event> new events) { final int currentCount = data.size(); synchronized(data) { data.addAll(events); } if (Looper.getMainLooper() == Looper.myLooper()) { notifyItemRangeInserted(currentCount, events.size()); } else { new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { notifyItemRangeInserted(currentCount, events.size()); } }); } } 

if else checks if you are calling addAll from the ui thread or from another thread and calling notifyItemRangeInserted safe way. In Activity , when onResponse is onResponse , after onResponse is completely populated eventsList just call eventListAdapter.addAll(eventsList)

+5
source

Source: https://habr.com/ru/post/1235522/


All Articles