W iOS istnieje bardzo łatwa i wydajna funkcja do animowania dodawania i usuwania wierszy UITableView, oto klip z filmu na YouTube pokazujący domyślną animację. Zwróć uwagę, jak otaczające rzędy zapadają się na usunięty wiersz. Ta animacja pomaga użytkownikom śledzić, co zmieniło się na liście i gdzie na liście patrzyli, kiedy zmieniły się dane.
Odkąd pracuję na Androidzie, nie znalazłem odpowiedniego narzędzia do animowania pojedynczych wierszy w TableView . Wywołanie notifyDataSetChanged()
mojego adaptera powoduje, że ListView natychmiast aktualizuje swoją zawartość o nowe informacje. Chciałbym pokazać prostą animację nowego wiersza wciskającego się lub wysuwającego, gdy zmieniają się dane, ale nie mogę znaleźć żadnego udokumentowanego sposobu, aby to zrobić. Wygląda na to, że LayoutAnimationController może mieć klucz do uruchomienia tego, ale kiedy ustawię LayoutAnimationController na moim ListView (podobnie do LayoutAnimation2 ApiDemo ) i usuwam elementy z mojego adaptera po wyświetleniu listy, elementy znikają natychmiast, zamiast zostać animowane .
Próbowałem też wykonać następujące czynności, aby animować pojedynczy element po jego usunięciu:
@Override
protected void onListItemClick(ListView l, View v, final int position, long id) {
Animation animation = new ScaleAnimation(1, 1, 1, 0);
animation.setDuration(100);
getListView().getChildAt(position).startAnimation(animation);
l.postDelayed(new Runnable() {
public void run() {
mStringList.remove(position);
mAdapter.notifyDataSetChanged();
}
}, 100);
}
Jednak rzędy otaczające animowany rząd nie zmieniają pozycji, dopóki nie zostaną przeskoczone na nowe pozycje, gdy notifyDataSetChanged()
zostanie wywołane. Wygląda na to, że ListView nie aktualizuje swojego układu po umieszczeniu jego elementów.
Podczas pisania własnej implementacji / rozwidlenia ListView przyszło mi do głowy, wydaje się, że nie powinno to być takie trudne.
Dzięki!
Odpowiedzi:
do animacji od góry do dołu:
źródło
anim.setAnimationListener(new AnimationListener() { ... })
zamiast HandlerapopulateList()
?Handler
. Po drugie, sprawia, że kod jest mniej skomplikowany dzięki użyciu wbudowanego wywołania zwrotnego na zakończenie animacji. Po trzecie, nie wiesz, jak wdrożenieHandler
iAnimation
będzie działać na każdej platformie; możliwe, że opóźnione uruchomienie nastąpi przed zakończeniem animacji.The
RecyclerView
Zajmuje dodawania, usuwania i ponownego zamawiania animacji!Ten prosty projekt AndroidStudio zawiera
RecyclerView
. spójrz na commity :źródło
Spójrz na rozwiązanie Google. Oto tylko metoda usuwania.
Kod projektu ListViewRemovalAnimation i demonstracja wideo
Wymaga Androida 4.1+ (API 16). Ale mamy 2014 rok na zewnątrz.
źródło
Ponieważ
ListViews
są wysoce zoptymalizowane, myślę, że nie jest to możliwe. Czy próbowałeś utworzyć „ListView” według kodu (tj. Nadmuchując swoje wiersze z xml i dołączając je do aLinearLayout
) i animując je?źródło
LinearLayout
, jednak przy bardzo dużych zestawach danychLinearLayout
wydajność będzie fatalna.ListView
ma wiele inteligentnych optymalizacji w zakresie recyklingu widoków, które pozwalają mu obsługiwać duże zestawy danych (UITableView na iOS ma te same optymalizacje). Pisanie własnego widoku recykler należy do kategorii ListViewCzy zastanawiałeś się nad animacją przeciągnięcia w prawo? Możesz zrobić coś takiego jak narysowanie coraz większego białego paska u góry elementu listy, a następnie usunięcie go z listy. Pozostałe komórki nadal szarpnęły się w miejscu, ale lepiej niż nic.
źródło
call listView.scheduleLayoutAnimation (); przed zmianą listy
źródło
Zhakowałem razem inny sposób, aby to zrobić bez konieczności manipulowania widokiem listy. Niestety zwykłe animacje na Androida zdają się manipulować zawartością wiersza, ale nieefektywnie zmniejszają widok. Więc najpierw rozważ ten moduł obsługi:
Dodaj tę kolekcję do adaptera listy:
i dodaj
Następnie, gdziekolwiek chcesz ukryć wiersz, dodaj to:
Otóż to! Szybkość animacji można zmienić, zmieniając liczbę pikseli zmniejszających wysokość jednocześnie. Nie bardzo wyrafinowane, ale działa!
źródło
Po wstawieniu nowego wiersza do ListView, po prostu przewijam ListView do nowej pozycji.
źródło
Nie próbowałem tego, ale wygląda na to, że animateLayoutChanges powinien zrobić to, czego szukasz. Widzę to w klasie ImageSwitcher, zakładam, że to także w klasie ViewSwitcher?
źródło
Ponieważ Android jest open source, tak naprawdę nie trzeba ponownie wdrażać optymalizacji ListView. Możesz pobrać kod ListView i spróbować znaleźć sposób na włamanie się do animacji, możesz także otworzyć żądanie funkcji w Android trackerze błędów (a jeśli zdecydowałeś się go wdrożyć, nie zapomnij dodać łatki ).
Do Twojej wiadomości, kod źródłowy ListView jest tutaj .
źródło
Oto kod źródłowy, który umożliwia usuwanie wierszy i zmianę ich kolejności.
Dostępny jest również plik demonstracyjny APK. Usuwanie wierszy odbywa się bardziej zgodnie z aplikacją Gmaila Google, która odsłania widok z dołu po przesunięciu widoku z góry. Widok z dołu może mieć przycisk Cofnij lub cokolwiek chcesz.
źródło
Tak jak wyjaśniłem moje podejście na mojej stronie, udostępniłem link. W każdym razie chodzi o tworzenie map bitowych przez getdrawingcache. Posiadanie dwóch map bitowych i animowanie dolnej mapy bitowej w celu uzyskania efektu ruchomego
Zobacz następujący kod:
Aby to zrozumieć, zobacz obrazy
Dzięki.
źródło
Zrobiłem coś podobnego do tego. Jednym z podejść jest interpolacja w czasie animacji wysokości widoku w czasie wewnątrz wierszy
onMeasure
podczas wystawianiarequestLayout()
dla listView. Tak, może być lepiej zrobić bezpośrednio na liścieView code, ale było to szybkie rozwiązanie (wyglądało dobrze!)źródło
Po prostu podziel się innym podejściem:
Pierwszy set widoku listy w Androidzie: animateLayoutChanges się prawdą :
Następnie używam modułu obsługi do dodawania elementów i aktualizowania widoku listy z opóźnieniem:
źródło