@DarkByte2015

Почему элементы списка подгружаются не так как надо?

Есть задача - сделать бесконечную ленту дат (календарь не канает). Я делаю ее на основе ListView. Сделал свой адаптер для массива дат и layout для элемента. Все работает, осталось только допилить логику подгрузки элементов при прокрутке. Я думаю это надо сделать как-то так: изначально список прокручен до последнего элемента (текущая дата) - сделал android:stackFromBottom="true" и в него загружены даты за последний год (но для теста сделал пока-что за последние несколько дней чтобы долго не листать), когда юзер начинает прокручивать список и доходит до верхней границы (или даже лучше заранее подгрузить firstVisibleItem < 5 например) то подгружаются элементы еще за год. Я все сделал - должно работать, но получилась хрень какая-то... Сначала все загружается нормально, но когда я начинаю скроллить - даты начинают лететь со страшной скоростью - все проматывается моментально аж на годы назад и вставляется в неправильном порядке. Я залогировал firstVisibleItem - он почему то все время в районе 4-6 находится, хотя по идее должен быть в конце списка (ну почти). Почему так происходит?

код
@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;
}

  • Вопрос задан
  • 225 просмотров
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Java
Android developer at Yandex
Имхо, сделано в лоб, сложно и неоптимально.
Я бы взял RecyclerView , в адаптере количество отдавал бы Integer.MAX_VALUE. В бинде по позиции вычислял бы дату(с помощью календаря).
Плюсы, кажется, очевидны - не нужен пейджинг, не нужно хранить список дат, не нужно сложной логики.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы