2014-06-19 9 views
7

z odpowiedzi na jedno z pozostałych pytań znalazłem Google Demo of a ListView subclass, który umożliwia zmianę pozycji.Co to jest VerticalScrollExtent w Android ScrollView?

Demo działa świetnie, ale mam problem z jego zrozumieniem: Gdy element jest przeciągany powyżej/poniżej granic ListView, ListView zaczyna przewijać w górę/w dół, aby odsłonić nowe elementy. Niezbędna kalkulacji wykorzystuje różne parametry Scrollview podwładnego:

public boolean handleMobileCellScroll(Rect r) {   
    int offset = computeVerticalScrollOffset(); 
    int height = getHeight(); 
    int extent = computeVerticalScrollExtent(); 
    int range = computeVerticalScrollRange(); 
    int hoverViewTop = r.top; 
    int hoverHeight = r.height();  

    if (hoverViewTop <= 0 && offset > 0) { 
     smoothScrollBy(-mSmoothScrollAmountAtEdge, 0); 
     return true; 
    } 

    if (hoverViewTop + hoverHeight >= height && (offset + extent) < range) { 
     smoothScrollBy(mSmoothScrollAmountAtEdge, 0); 
     return true; 
    } 

    return false; 
} 
  • height jest wysokość ListView samego
  • offset jest pozycja przewijania = ile jednostek/piksele były przewijane w górę/w dół
  • range to wysokość pełnej zawartości.
  • extent - cóż, co to jest?

ListView dziedziczy computeVerticalScrollExtent() z View i docu mówi:

obliczyć pionowe przesunięcie kciukiem pionowy pasek przewijania w ciągu zakresie poziomym. Ta wartość służy do obliczenia położenia kciuka wewnątrz ścieżki paska przewijania.

Jeśli ktoś patrzy na codecomputeVerticalScrollExtent() nie jest realizowany przez jednego z sublasses ale tylko bezpośrednio przez View: To po prostu zwraca wysokość widoku.

Ma to sens: jeśli ListView/ScrollView ma wysokość 500, to część wyświetlanej zawartości przewijania również wynosi 500. Czy to jest znaczenie ScrollExtent? Dlaczego wymagany jest ScrollExtent? Dlaczego po prostu nie użyjesz getHeight() bezpośrednio?

Myślę, że czegoś brakuje i cieszę się z jakiejkolwiek wskazówki!

+1

Czy mieli więcej informacji na temat „przedłużyć”? Jestem trochę blokować na to zbyt –

+0

To jest przykładowy kod, który może pomóc zrozumieć, w jaki sposób dostać się pasek przewijania góra i dół za pomocą computeVerticalScrollExtent: { scrollbarTop = (float) this.computeVerticalScrollExtent()/this.computeVerticalScrollRange() * this.computeVerticalScrollOffset(); scrollbarBottom = (float) this.computeVerticalScrollExtent()/this.computeVerticalScrollRange() * (this.computeVerticalScrollExtent() + this.computeVerticalScrollOffset()); } – Shilpi

Odpowiedz

2

Trochę za późno, ale mam nadzieję, że wszystko w porządku.

1) Metoda faktycznie jest zaimplementowana przez podklasy. Na przykład, this jest tym, co wygląda dla nadklasy AbsListView (ListView).
2) View Wysokość może być inna niż wysokość pionowego przewijania - wystarczy wyobrazić sobie View z dziwnym wypełnieniem górą/dołem.

tymi dwoma punktami dość dużo zrobić inne pytania nieistotne :)

1

To jest przykładowy kod, który może pomóc zrozumieć, w jaki sposób dostać się pasek przewijania góra i dół za pomocą computeVerticalScrollExtent:

scrollbarTop = (float)this.computeVerticalScrollExtent()/this.computeVerticalScrollRange()*this‌​.computeVerticalScrollOffset(); 

scrollbarBottom = (float)this.computeVerticalScrollExtent()/this.computeVerticalScrollRange()*(thi‌​s.computeVerticalScrollExtent()+this.computeVerticalScrollOffset()); 
4
  • Compute * ScrollOffset - Określa odległość między początkiem przewijalnego obszaru a górną częścią bieżącego okna widoku w przewijanym obszarze. Na przykład, jeśli twoja lista zawiera 10 elementów i przewiniesz w dół, aby trzeci element znajdował się w najbardziej widocznym miejscu, przesunięcie wynosi 3 (lub 3 * itemHeight, patrz poniżej).

  • Compute * ScrollExtent - Określa rozmiar bieżącego okna widoku wewnątrz przewijalnego obszaru. Na przykład, jeśli twoja lista zawiera 10 przedmiotów, a obecnie możesz zobaczyć 5 takich przedmiotów, to zakres wynosi 5 (lub 5 * itemHeight, patrz poniżej).

  • obliczenie * ScrollRange - Określa rozmiar aktualnie przewijanego obszaru. Na przykład, jeśli twoja lista ma 10 przedmiotów, to zakres wynosi 10 (lub 10 * itemHeight, patrz poniżej).

pamiętać, że wszystkie te metody mogą zwracać wartości w różnych jednostkach w zależności od ich realizacji, więc na powyższych przykładach, używam indeksów, ale w niektórych przypadkach te metody zwróci wartości pikseli równoważne do szerokości lub wysokość przedmiotów.

W szczególności, LinearLayoutManager z RecyclerView zwróci indeksy, jeśli funkcja "smooth scrollbar" jest włączona, w przeciwnym razie zwróci wartości pikseli. Zobacz ScrollbarHelper w bibliotece pomocy technicznej, aby uzyskać więcej informacji.

Dodatkowa lektura: https://groups.google.com/forum/#!topic/android-developers/Hxe-bjtQVvk