Как определить, когда просмотр списка FMX прокручивается вниз?
Я работаю над Firemonkey TListView
для отображения результатов поиска. Этот список загружает 25 элементов одновременно, но потенциально может отображать сотни элементов.
Мне нужно определить, когда пользователь прокрутил страницу до конца, чтобы я мог выбрать следующие 25 элементов для отображения в списке. Тем не менее, я не могу найти соответствующие свойства, чтобы определить это.
Там есть OnPullRefresh
событие, но это относится к прокрутке в верхней части списка и потянув его вниз. Что мне нужно, это похоже, но для нижней части списка, а не сверху.
Там есть OnScrollViewChange
событие, которое кажется уместным. Там также ScrollViewPos
свойство, которое также полезно. Однако я не могу понять, с чем сравнивать это число, в частности, с максимально возможным значением для ScrollViewPos
, Что-то вроде ScrollViewMax
это то, что мне нужно
Но я не могу найти ничего более точного, чтобы точно определить, что пользователь прокрутил до дна.
Как я могу определить, когда пользователь прокрутил до конца Firemonkey? TListView
чтобы я мог загрузить больше результатов поиска?
РЕДАКТИРОВАТЬ
Если это невозможно по какой-либо причине, есть альтернатива, чтобы добавить фиктивный элемент в конец списка с помощью кнопки "Загрузить еще...". Но я бы предпочел, чтобы это было автоматизировано.
EDIT2
Я забыл упомянуть... У меня есть окно поиска, отображаемое в этом списке, и элементы могут иметь переменную высоту. Если это вычисление на основе содержимого элемента является единственным способом, то такой расчет должен быть идеальным. Я не хочу знать, когда пользователь "приближается" или "приближается" ко дну, но когда пользователь точно попадает в конец списка.
2 ответа
Дальнейшее расследование я обнаружил в
function TListViewBase.GetItemRect(const AItemIndex: Integer): TRectF;
Если вы идете глубже в
function TListViewBase.GetItemRelRect(const Index: Integer; const LocRect: TRectF;
const SideSpace: Integer = 0): TRectF;
тогда вы поймете, что топ последнего элемента
listview1.GetItemRect(listview1.ItemCount-1).top+listview1.ScrollViewPos-listview1.SideSpace-listview1.LocalRect.top
какими бы ни были ваши предметы переменной высоты. Это представляет ценность FHeightSums[Index]
который является списком, содержащим сумму высоты до элемента с индексом Index
Теперь к проблеме: вы хотите, чтобы расчет был идеальным. Вы хотите прикоснуться.
И это все
procedure TForm5.ListView1ScrollViewChange(Sender: TObject);
var
Tmp_top : single;
begin
Tmp_top := listview1.GetItemRect(listview1.ItemCount-1).top+listview1.ScrollViewPos-listview1.SideSpace-listview1.LocalRect.top;
if Tmp_top+listview1.GetItemRect(listview1.ItemCount-1).height-listview1.Height=listview1.ScrollViewPos-2*listview1.SideSpace then
showmessage('touch down');
end;
Изменить: если вы еще больше упростите эту формулу, вы получите другой ответ с несколькими обновлениями
procedure TForm5.ListView1ScrollViewChange(Sender: TObject);
begin
if listview1.GetItemRect(listview1.ItemCount-1).bottom=listview1.Height-listview1.SideSpace then
showmessage('touch down');
end;
теперь это будет охватывать любые изменения в отступах, полях, боковом пространстве, видимости окна поиска и изменении размера окна поиска.
Попробуйте этот код. Самоочевидно, я думаю...
procedure TForm1.ListView1ScrollViewChange(Sender: TObject);
var
R: TRectF;
begin
if TListView(Sender).ItemCount > 0 then // Just in case...
begin
// Get the last item's Rect
R := TListView(Sender).GetItemRect(TListView(Sender).ItemCount - 1);
// Bottom?
if R.Bottom = TListView(Sender).Height then
Caption := 'Reached bottom!'
else
Caption := 'Bottom not reached yet.';
end;
end;