2017-09-19 4 views
1

Je travaille sur un Firemonkey TListView pour afficher les résultats de la recherche. Cette liste charge 25 éléments à la fois, mais pourrait potentiellement afficher des centaines d'éléments.Comment détecter quand FMX List View défile vers le bas?

J'ai besoin de détecter quand l'utilisateur a fait défiler vers le bas, de sorte que je puisse aller chercher les 25 éléments suivants à afficher dans la liste. Cependant, je ne peux pas trouver les propriétés appropriées pour le déterminer.

Il y a l'événement OnPullRefresh, mais cela s'applique au défilement vers le haut de la liste et au retrait. Ce dont j'ai besoin est similaire, mais pour le en bas de la liste au lieu du en haut.

Il y a l'événement OnScrollViewChange, ce qui semble approprié. Il y a aussi la propriété ScrollViewPos, qui est également utile. Cependant, je ne peux pas savoir quoi comparer ce nombre à - en particulier, la valeur maximale possible pour ScrollViewPos. Quelque chose comme ScrollViewMax est ce dont j'aurais besoin.

Mais je ne trouve rien de plus pour détecter avec précision que l'utilisateur a fait défiler vers le bas.

Comment puis-je détecter lorsqu'un utilisateur a fait défiler vers le bas d'un Firemonkey TListView afin que je puisse charger plus de résultats de recherche?

EDIT

Si cela est impossible pour une raison quelconque, il existe une alternative pour ajouter un élément factice à la fin de la liste avec un bouton « Plus ... Load ». Mais je préférerais que ce soit automatisé.

EDIT2

j'oublié de mentionner ... J'ai la boîte de recherche montrant à ce point de vue de la liste et les articles peuvent avoir une hauteur variable. Si le calcul basé sur le contenu de l'article est le seul moyen, alors un tel calcul doit être parfait. Je ne veux pas savoir quand l'utilisateur «approche» ou «s'approche» du bas, mais quand l'utilisateur atteint exactement le bas de la liste.

+0

Ok, alors regardez la source de la méthode ScrollTo qui défile vers un élément spécifique. –

Répondre

1

enquête De plus, je trouve ce qui suit dans

function TListViewBase.GetItemRect(const AItemIndex: Integer): TRectF; 

Si vous aller plus loin dans

function TListViewBase.GetItemRelRect(const Index: Integer; const LocRect: TRectF; 
    const SideSpace: Integer = 0): TRectF; 

alors vous vous rendrez compte que le dernier de l'article Top est

listview1.GetItemRect(listview1.ItemCount-1).top+listview1.ScrollViewPos-listview1.SideSpace-listview1.LocalRect.top 

tout ce qui était votre articles hauteur variable. Cela représente la valeur de FHeightSums[Index] qui est une liste contenant la somme de la hauteur jusqu'à ce que l'élément avec Index Index

maintenant au problème:Vous voulez que le calcul soit parfait. vous voulez un contact.

Et c'est-il

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; 

Edit: si vous simplifiera davantage cette formule vous finirez dans l'autre réponse avec quelques améliorations

procedure TForm5.ListView1ScrollViewChange(Sender: TObject); 
begin 

if listview1.GetItemRect(listview1.ItemCount-1).bottom=listview1.Height-listview1.SideSpace then 
    showmessage('touch down'); 

end; 

maintenant cela couvrira toute modification dans le remplissage, les marges, l'espace latéral, la visibilité de la zone de recherche et le changement de taille de la zone de recherche.

+0

Ne fonctionnera pas correctement s'il y a une boîte de recherche ou si les articles sont d'une hauteur variable (que j'ai les deux). Aussi pas tout à fait sûr sur les marges/rembourrage. Cela pourrait être une formule beaucoup plus difficile, car j'en ai besoin pour correspondre exactement. –

+1

@JerryDodge Je viens de tester le champ de recherche et la formule n'est pas affectée. Quant à la hauteur variable de l'article, elle n'était pas mentionnée dans la question. Je pense que vous devriez ajouter cela. Cependant, je vais essayer de trouver quelque chose de mieux et de revenir à vous –

+0

@JerryDodge a fait la deuxième formule de travail pour vous? –

1

Essayez ce code. Je pense ...

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; 
+0

J'aime cette réponse, c'est plus simple et j'utilise seulement un appel de 'GetItemRect()'. Cependant, il échouera et ne fonctionnera pas si l'espace latéral change, heureusement je sais comment y remédier depuis que ma réponse couvre ceci :). pour surmonter ce changement la condition if de 'R.Bottom = TListView (Sender) .Height' à' R.Bottom = TListView (Sender) .Height - TListView (Sender) .SideSpace' et c'est fait –

+0

Aussi le premier si est inutile parce qu'il y a une possibilité d'avoir sept ou 15 éléments et les barres de défilement ne seront pas visibles. Il ne sera visible que lorsque la hauteur totale des éléments est supérieure à la hauteur de la toile. En conclusion, le cas où il n'y a pas d'éléments et les barres de défilement ne sont pas possibles (au moins pour cette question) –

+0

Je viens de le remarquer. Si je simplifie ma deuxième formule je me retrouve dans votre réponse (bien sûr avec la modification que je vous ai dite) –