5

Biblioteka RecyclerView ostatnio dodała nową klasę SortedList. Załóżmy, że mam wywołanie zwrotne, które implementuje metodę compare(), która może się zmieniać w czasie, tj. Bazowy Komparator może zostać wyłączony. Jaki jest najlepszy sposób, aby powiedzieć SortedList, aby w pełni wykorzystać swoje dane?Jak całkowicie uciec RecyclerView's SortedList

+1

Gdybym musiał zgadywać, 'beginBatchedUpdates()', 'recalculatePositionOfItemAt()' (dla każdego przedmiotu) i 'endBatchedUpdates()', ale to tylko domysły oparte na API. – CommonsWare

+0

najgorszy scenariusz, http://developer.android.com/reference/android/support/v7/widget/util/SortedListAdapterCallback.html wywołanie zwrotne ma metody, kiedy element jest zmieniany, ale właściwą odpowiedzią jest prawdopodobnie @CommonsWare ' s odpowiedź. – EpicPandaForce

+0

To nie jest zły początek. Ale wywoływanie recalculatePositionOfItemAt() dla każdego indeksu nie ucieknie go całkowicie. Indeksy ulegną zmianie, co prowadzi do pominięcia niektórych elementów. –

Odpowiedz

1

Oto moje własne spojrzenie na niego (napisany w Kotlin):

list.beginBatchedUpdates() 

val indices = (0..list.size() - 1).toArrayList() 

while (!indices.isEmpty()) { 
    val i = indices.first() 
    val item = list.get(i) 

    list.recalculatePositionOfItemAt(i) 

    [suppress("USELESS_CAST_STATIC_ASSERT_IS_FINE")] 
    indices.remove(list.indexOf(item) as Any) //cast to disambiguate remove() 
} 

list.endBatchedUpdates() 

Jak widać, jestem śledzenia nowego indeksu po każdym wywołaniu recalculatePositionOfItemAt() więc każdy element uciekamy się tylko raz i nie ma pozycji jest pomijany.

To działa, ale wydaje się być naprawdę nieekonomiczne, ponieważ recalculatePositionOfItemAt() zmieni dwukrotnie rozmiar podstawowej tablicy, aby usunąć, a następnie odczytać element. indexOf następnie wykona nowe wyszukiwanie binarne, mimo że indeks jest już znany.

Edytuj: To wydaje się prowadzić do nieskończonej pętli, jeśli elementy są porównywane jako równe.

Alternatywne podejście (usuń wszystko, a następnie dodać wszystkie):

list.beginBatchedUpdates() 

val copy = (list.size() - 1 downTo 0).map { list.removeItemAt(it) } 
copy.forEach { list.add(it) } 

list.endBatchedUpdates() 
0

Niestety, nie ma do tego API. Wystarczy skopiować źródło i samodzielnie dodać tę metodę. Dane kopii zapasowej to tylko tablica, więc możesz wywołać na niej plik Arrays.sort, a następnie zmienić zestaw danych powiadomień. Zmiany w śledzeniu nie są banalne, gdy cały świat się zmienia, więc nie jest tak naprawdę odpowiedni przypadek dla posortowanej listy. Utwórz żądanie funkcji na stronie b.Android.com.

+0

Tak, zdałem sobie sprawę, że animowanie kompletnego uciekania się na więcej niż 5 przedmiotach wygląda tak naprawdę dziwnie. –

+0

Btw, nie musisz kopiować źródła. Ponieważ podstawowa tablica mData jest pakietem prywatnym, możesz uzyskać do niej dostęp za pośrednictwem helpera w tym samym pakiecie. –