Доброго времени суток!
Сегодня хотел бы рассмотреть динамическую подгрузку контента.
Мы не так давно в нашем ламповом чатике обсуждали два варианта подгрузки данных:
Остальной код который выполняет запросы и заполнение списка, также имеет комментарии. Его можно посмотреть на GitHub'e
Сегодня хотел бы рассмотреть динамическую подгрузку контента.
Мы не так давно в нашем ламповом чатике обсуждали два варианта подгрузки данных:
- Бесконечный скроллинг (например как лента в ВК)
- Паджинация/Пагинация (постраничная загрузка)
В современных приложениях почти всегда используется бесконечный скроллинг, это удобно по нескольким причинам:
- Пользователю не нужно дотягиваться до кнопок переключения страниц или использовать жесты влево/вправо
- Разработчику не нужно искать место для размещения контролов переключения страниц или реализовывать доп. функционал по управлению паджинацией с помощью жестов
Было свободное время и я реализовал два этих варианта с применением ModernListView, т.к. в нём есть специальные методы и события для простой реализации.
Опишу немного как всё это работает:
На сервер отправляется запрос с указанием страницы, PHP скрипт сформирует массив из имён статичных файлов (картинок) и упакует это в JSON формат. Наш клиент принимает JSON и отображает информацию в списке. При прокрутке контента происходит динамическая подгрузка картинок с сервера.
Для удобного использования я создал помощника (комментарии присутствуют)
Опишу немного как всё это работает:
На сервер отправляется запрос с указанием страницы, PHP скрипт сформирует массив из имён статичных файлов (картинок) и упакует это в JSON формат. Наш клиент принимает JSON и отображает информацию в списке. При прокрутке контента происходит динамическая подгрузка картинок с сервера.
Для удобного использования я создал помощника (комментарии присутствуют)
type TmyLVLoadMode = (Scrolling, Pages); TmyLVDynamicLoad = record // настраиваем LV class procedure configList(const aLV: TListView); static; // режим подгрузки данных class var LoadMode: TmyLVLoadMode; // кол-во страниц class function PageCount: integer; static; // текущая страница class var Page: integer; // загрузка нужной страницы class procedure LoadPage(const aLV: TListView; const aPage: integer; const aLabel: TLabel); static; end;Вот весь листинг основного модуля, вся работа происходит в недрах помощника
procedure TFormMain.btnPrevClick(Sender: TObject); begin // загружаем предыдущую страницу TmyLVDynamicLoad.LoadPage(ListView1, TmyLVDynamicLoad.Page - 1, lbText); end; procedure TFormMain.btnNextClick(Sender: TObject); begin // загружаем следующую страницу TmyLVDynamicLoad.LoadPage(ListView1, TmyLVDynamicLoad.Page + 1, lbText); end; procedure TFormMain.FormShow(Sender: TObject); begin // настраиваем отображение ListView TmyLVDynamicLoad.configList(ListView1); // выбираем режим подгрузки Scrolling SetLVMode(false); end; procedure TFormMain.ListView1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); var I: integer; aLV: TListView; aFirst, aLast: integer; begin aLV := (Sender as TListView); if (aLV.Items.Count <= 0) then exit; // получаем первый видимый элемент aFirst := Max(0, aLV.getFirstVisibleItemIndex); // получаем кол-во видимых элементов aLast := aFirst + aLV.getVisibleCount; for I := aFirst to aLast do begin // находится ли наш индекс в нужном диапозоне if InRange(I, 0, aLV.Items.Count - 1) then begin // если картинка еще не была загружена, то начинаем её грузить if aLV.Items[I].Data[sign_Loaded].AsInteger = 0 then begin // начали загружать! aLV.Items[I].Data[sign_Loaded] := 1; // собственно загрузка картинки, в доп. потоке LoadBitmapFromURL(aLV.Items[I].Data[sign_URL].AsString, aLV.Items[I].Bitmap); end; end; end; end; procedure TFormMain.OnLVScrollEnd(Sender: TObject); begin if TmyLVDynamicLoad.Page < TmyLVDynamicLoad.PageCount then begin // в режиме скроллинга всегда грузим следующую страницу TmyLVDynamicLoad.LoadPage(ListView1, TmyLVDynamicLoad.Page + 1, lbText); sleep(1500); // делаем паузу, имитируем диалог ожидания end; end; procedure TFormMain.SetLVMode(const aValue: Boolean); begin ListView1.ItemsClearTrue; if aValue then begin // меняем режим подгрузки на паджинацию TmyLVDynamicLoad.LoadMode := TmyLVLoadMode.Pages; lbText.Text := 'Pages / page = 1'; // в режиме паджинации обнуляем событие ListView1.OnScrollEnd := nil; // показываем контролы управления паджинацией btnNext.Visible := true; btnPrev.Visible := true; end else begin // меняем режим подгрузки на бесконечный скроллинг TmyLVDynamicLoad.LoadMode := TmyLVLoadMode.Scrolling; lbText.Text := 'Scrolling / page = 1'; // назначаем событие при котором будет вызываться подгрузка следующей порции ListView1.OnScrollEnd := OnLVScrollEnd; // скрываем контролы управления паджинацией btnPrev.Visible := false; btnNext.Visible := false; end; // после смены режима подгрузки, загружаем первую страницу TmyLVDynamicLoad.LoadPage(ListView1, 1, lbText); end; procedure TFormMain.Switch1Switch(Sender: TObject); begin SetLVMode(Switch1.IsChecked); end;
Остальной код который выполняет запросы и заполнение списка, также имеет комментарии. Его можно посмотреть на GitHub'e
Используемые модули
- ModernListView
- XSuperObject - для чтения JSON данных
- FMX.HTTP.Request - кроссплатформенная библиотека для запросов на основе THTTPClient
А вот, как сделал я бесконечный скроллинг.
ОтветитьУдалитьhttp://www.kyrylych.tk/