1

I have a problem with my Recyclerview and I can not find a solution to resolve it. Indeed, my Recyclerview is supposed to display data received from an external database. But sometimes, it displays the data, sometimes not.

This is the screenshots of my app :

When data are displayed

When data are not displayed

And this is my Adapter's code :

public class UpcomingLessonAdapter extends RecyclerView.Adapter<UpcomingLessonAdapter.ViewHolder> {

private List<Lesson> lessons;
private LayoutInflater inflater;

public UpcomingLessonAdapter(List<Lesson> lessons, Context context) {
    this.lessons = lessons;
    inflater = LayoutInflater.from(context);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = inflater.inflate(R.layout.upcoming_lesson_list_view, parent, false);
    itemView.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
    return new UpcomingLessonAdapter.ViewHolder(itemView);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    final Lesson lesson = lessons.get(position);

    String lessonTopic = "<font color='#E166E1'>" + lesson.getTopicTitle() + "</font>";
    String userName = "<font color='#E166E1'>" + lesson.getUserName() + "</font>";

    holder.lessonTopic.setText(Html.fromHtml(lesson.getTime(lesson.getTimeStart()) + " " + lessonTopic));
    holder.lessonTeacher.setText(Html.fromHtml("avec " + userName));
    holder.lessonDuration.setText(lesson.getDuration());
    holder.lessonDay.setText(lesson.getDay(lesson.getTimeStart()));
    holder.lessonMonth.setText(lesson.getMonth(lesson.getTimeStart()));

}

@Override
public int getItemCount() {
    return lessons.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder{
    TextView lessonTopic, lessonTeacher, lessonDuration, lessonDay, lessonMonth;

    public ViewHolder(View itemView) {
        super(itemView);
        lessonTopic = (TextView) itemView.findViewById(R.id.lesson_topic_text_view);
        lessonTeacher = (TextView) itemView.findViewById(R.id.lesson_teacher_text_view);
        lessonDuration = (TextView) itemView.findViewById(R.id.lesson_duration_text_view);
        lessonDay = (TextView) itemView.findViewById(R.id.lessson_day_text_view);
        lessonMonth = (TextView) itemView.findViewById(R.id.lesson_month_text_view);
    }
}

}

And this the method in my fragment when I create the recyclerview :

public void displayUpcomingLessonListView() {
    upcomingLessonRecyclerView = (RecyclerView) view.findViewById(R.id.upcoming_lesson);
    upcomingLessonAdapter = new UpcomingLessonAdapter(upcomingLessons, getContext());
    upcomingLessonLayoutManager = new LinearLayoutManager(getContext());
    upcomingLessonRecyclerView.setLayoutManager(upcomingLessonLayoutManager);
    upcomingLessonRecyclerView.setItemAnimator(new DefaultItemAnimator());
    upcomingLessonRecyclerView.setAdapter(upcomingLessonAdapter);
}

Is there anyone who can give me some advice ? Thanks in advance.

Best regards,

EDIT

This the method by which I fetch my data :

public void getLessonInfos(final int lessonId, final int index, final List<Lesson> lessons) {
    Call<JsonResponse> call = service.getLessonInfos(lessonId, user.getEmail(), user.getToken());
    call.enqueue(new Callback<JsonResponse>() {
        @Override
        public void onResponse(Call<JsonResponse> call, Response<JsonResponse> response) {
            lessons.get(index).setUserName(response.body().getUserName());
            lessons.get(index).setTopicTitle(response.body().getTopicTitle());
            lessons.get(index).setTopicGroupTitle(response.body().getTopicGroupTitle());
            lessons.get(index).setLevel(response.body().getLevelTitle());
            lessons.get(index).setDuration(response.body().getDuration().getHours(), response.body().getDuration().getMinutes());
            lessons.get(index).setStatus(response.body().getLessonStatus());


            if (upcomingLessons.size() > 0) {
                if (lessonId == upcomingLessons.get(upcomingLessons.size() - 1).getLessonId()) {
                    displayUpcomingLessonListView();
                }
            }
        }

        @Override
        public void onFailure(Call<JsonResponse> call, Throwable t) {

        }
    });
}
Wivi0
  • 11
  • 4

2 Answers2

0
  try {
         ResponseBody response = call.execute().body();
    } catch (IOException e) {
        e.printStackTrace();
    }

Alright when you invoke methods asynchronously , the network makes a request then , waits for a response. The latency or rather rather time will vary based on your connection speed(bytes per second) or rather your data-set(lots of data ,take time to process). Therefore the reason why your code sometime works is because some time the request and response time is fast enough to update your data in time.The snippet above remove the aforementioned method ,thus divorcing the concept of waiting for response. It makes a request synchronously and gets a response immediately. There is no wait time, the only time waited is the time to get the data from what ever source it is stored, process such data, transform it and send it off.

Remario
  • 3,813
  • 2
  • 18
  • 25
  • enqueue makes your request asynchronous, but execute makes it synchronous. just manipulate response object now,make sense? – Remario Mar 09 '17 at 12:17
  • Yes :-) Thank you ! – Wivi0 Mar 09 '17 at 14:29
  • no problem, however just make sure that your data set is small. Ill provide a more in dept explanation for this hack. Both the bad and good. – Remario Mar 09 '17 at 14:31
  • @CaspainCaldion Hi, please provide some context for the code, maybe edit your comments and use them in your answer? Useful resource for answering - stackoverflow.com/help/how-to-answer Thanks! – Eel Lee Mar 09 '17 at 15:45
0

Use ternary operator like

holder.lessonDuration.setText(lesson.getDuration()!=null?lesson.getDuration():"");

Rajesh
  • 2,618
  • 19
  • 25