D
D
DarkByte20152017-05-26 10:14:39
Java
DarkByte2015, 2017-05-26 10:14:39

Why are list items not loading properly?

There is a task - to make an endless tape of dates (the calendar does not channel). I make it based on ListView. I made my own adapter for the array of dates and layout for the element. Everything works, it remains only to finish the logic of loading elements when scrolling. I think it should be done something like this: initially the list is scrolled to the last element (current date) - I did android:stackFromBottom="true" and the dates for the last year are loaded into it (but for the test I did so far for the last few days to do not scroll for a long time), when the user starts scrolling the list and reaches the upper border (or even better to load firstVisibleItem < 5 in advance for example), then the elements are loaded for another year. I did everything - it should work, but it turned out some kind of crap ... At first everything loads normally, but when I start scrolling - the dates start to fly at a terrible speed - everything is instantly scrolled back as much as years and inserted in the wrong order. I pledged firstVisibleItem - for some reason it is always in the 4-6 region, although in theory it should be at the end of the list (well, almost). Why is this happening?

the code
@BindView(R.id.datesList)
ListView datesList;

final ArrayList<DateTime> dates = new ArrayList<>();

в MainActivity.onCreate
addDatesRange(DateTime.now());
final DatesAdapter adapter = new DatesAdapter(this, R.layout.date_item, dates);
datesList.setAdapter(adapter);

datesList.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        String msg = String.format("onScroll: firstVisibleItem = %d, visibleItemCount = %d, totalItemCount = %d", firstVisibleItem, visibleItemCount, totalItemCount);
        System.out.println(msg);

        if (totalItemCount > 5 && firstVisibleItem < 5) {
            addDatesRange(dates.get(0).minusDays(1));
            adapter.notifyDataSetChanged();
        }
    }
});

private void addDatesRange(DateTime end) {
  DateTime start = end.minusDays(6); //end.minusYears(1);

  String msg = String.format("addDatesRange: start = %s, end = %s", start.toString("dd.MM.yyyy"), end.toString("dd.MM.yyyy"));
  System.out.println(msg);

  dates.addAll(0, getDatesRange(start, end));
}

public static ArrayList<DateTime> getDatesRange(DateTime start, DateTime end) {
  ArrayList<DateTime> result = new ArrayList<>();

  while (start.isBefore(end)) {
      result.add(start);
      start = start.plusDays(1);
  }

  result.add(start);
  return result;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis Zagaevsky, 2017-05-26
@DarkByte2015

IMHO, done on the forehead, difficult and suboptimal.
I would take RecyclerView , in the adapter I would give Integer.MAX_VALUE. In a bind by position, I would calculate the date (using the calendar).
The pros seem to be obvious - no need for paging, no need to store a list of dates, no need for complex logic.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question