2013-12-17 41 views

Odpowiedz

49

Finał Aktualizacja

Minęło sporo czasu, odkąd napisał tę odpowiedź. Od tego czasu wiele się zmieniło. Największa zmiana polega na wprowadzeniu RecyclerView, która ułatwia animowanie listy lub siatki. Gorąco polecam przejście na RecyclerView s, jeśli możesz. Dla tych, którzy nie mogą, zobaczę, co mogę zrobić, aby naprawić błędy w mojej bibliotece.


odpowiedź Original

I rzeczywiście nie lubią popularny realizację animowanej ExpandableListView że po prostu używa ListView ze związkiem poszerzyć animacji bo w moim przypadku użycia, każdy z moich grup miał dużo dzieci, dlatego nie było możliwe używanie zwykłego ListView, ponieważ widoki podrzędne nie zostaną poddane recyklingowi, a wykorzystanie pamięci będzie ogromne przy niskiej wydajności. Zamiast tego poszedłem z dużo trudniejszym, ale bardziej skalowalnym i elastycznym podejściem.

Rozszerzyłem klasę ExpandableListView i przejąłem funkcje onCollapse i onExpand. Stworzyłem również podklasę BaseExpandableListAdapter o nazwie AnimatedExpandableListAdapter. Wewnątrz adaptera przejęłam funkcję getChildView i wykonałam funkcję końcową, aby funkcja nie mogła zostać przejęta ponownie. Zamiast tego podałem inną funkcję o nazwie getRealChildView dla podklas, aby zastąpić, aby zapewnić prawdziwy widok podrzędny. Następnie dodałem flagę animacji do klasy i spowodowałem, że getChildView zwróci fikcyjny widok, jeśli flaga animacji została ustawiona, i prawdziwy widok, jeśli flaga nie została ustawiona. Teraz z zestawem scen wykonuję następujące czynności w trybie onExpand:

  1. Ustaw flagę animacji w adapterze i powiedz adapterowi, która grupa się rozwija.
  2. Zadzwoń pod notifyDataSetChanged() (zmusza adapter do wywołania getChildView() dla wszystkich widoków na ekranie).
  3. Adapter (w trybie animacji) utworzy fałszywy widok dla grupy rozwijanej o początkowej wysokości 0. Adapter uzyska wówczas rzeczywiste widoki podrzędne i przekaże te widoki do widoku fałszywego.
  4. Widok typu dummy zacznie rysować rzeczywiste widoki podrzędne w ramach własnej funkcji onDraw().
  5. Adapter wyruszy w pętlę animacji, która rozwinie fikcyjny widok, dopóki nie będzie odpowiedniego rozmiaru. Ustawi także program nasłuchujący animację, aby mógł wyczyścić flagę animacji po zakończeniu animacji i zadzwoni pod numer notifyDataSetChanged().

W końcu, po wykonaniu wszystkich tych czynności, udało mi się nie tylko uzyskać pożądany efekt animacji, ale także pożądaną wydajność, ponieważ ta metoda będzie działać z grupą ponad 100 dzieci.

W przypadku animacji zwijania należy wykonać nieco więcej pracy, aby uzyskać tę konfigurację i działanie. W szczególności, gdy przesłonisz przy zwinięciu, nie chcesz wywoływać funkcji rodzica, ponieważ spowoduje to zwinięcie grupy natychmiast, nie dając szansy na odtworzenie animacji. Zamiast tego chcesz wywołać super.onCollapse na końcu animacji zwijania.

UPDATE:

Spędziłem trochę czasu w ten weekend przepisać moje wykonanie niniejszej AnimatedExpandableListView i jestem zwalniając źródło z przykładem użycia tutaj: https://github.com/idunnololz/AnimatedExpandableListView/

+0

Rozszerzalny widok listy działa świetnie. Uwielbiam animację :) –

+0

Uwielbiam twój widget, ale mam z tym duży problem: Moje widoki podrzędne to dość duży obraz (360x150), w którym używam typowej pamięci podręcznej cache/pamięci preload/sd. Gdy wywołuję metodę notifyDataSetChanged, występuje bardzo małe migotanie. Za pomocą widgetu migotanie jest bardzo zauważalne, otrzymuję go 2-3 razy na grupę rozwijania/zwijania, przy każdym wywołaniu funkcji notifyDataSetChanged(). Myślę, że bardzo trudno będzie się go pozbyć, ponieważ mniej więcej rozumiem, dlaczego tak się dzieje (twoja sztuczka z fałszywymi widokami, a następnie wywołanie prawdziwego notifyDataSet ...). Czy myślisz, że mogę złagodzić ten efekt za pomocą pamięci podręcznej/pamięci graficznej? – rupps

+1

@idunnololz, próbowałem twojej biblioteki, działa fantastycznie, dziękuję ci za wspaniałą bibliotekę. Chciałbym wiedzieć, że mam kursor z bazy danych, potrzebuję tego samego efektu za pomocą kursora, z listą tablic to działa dobrze, co zrobić dla kursorów ?. jakiejkolwiek pomocy, podpowiedzi lub sugestii z twojego końca. Z góry dziękuję – Naruto

6

rozwiązanie @idunnololz działa świetnie. jednak chciałbym dodać jakiś kod, aby zwinąć wcześniej rozwiniętą grupę.

private int previousGroup=-1; 

    listView.setOnGroupClickListener(new OnGroupClickListener() { 

     @Override 
     public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { 
      // We call collapseGroupWithAnimation(int) and 
      // expandGroupWithAnimation(int) to animate group 
      // expansion/collapse. 
      if (listView.isGroupExpanded(groupPosition)) { 
       listView.collapseGroupWithAnimation(groupPosition); 
       previousGroup=-1; 
      } else { 
       listView.expandGroupWithAnimation(groupPosition); 
       if(previousGroup!=-1){ 
        listView.collapseGroupWithAnimation(previousGroup); 
       } 
       previousGroup=groupPosition; 
      } 

      return true; 
     } 

    }); 
+1

Świetnie. Jedyne, czego brakuje, to skupienie aktualnie wybranej grupy. Na przykład, aby przenieść listę w taki sposób, aby obecny nagłówek znajdował się u góry ekranu. – Dimmy3

1
animateLayoutChanges adds auto-animation 
<ExpandableListView 
     android:animateLayoutChanges="true" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"/> 
0

rozwiązanie @idunnololz działa świetnie, ale przeżyłem dziwne zachowanie z mojej dostosowanych do grupy. Operacja rozwijania nie została wykonana poprawnie, ale zwinięcie działało idealnie. Zaimportowałem jego testowy projekt i działało dobrze, więc zdałem sobie sprawę, że problem dotyczy mojego niestandardowego układu. Jednak, kiedy nie był w stanie zlokalizować problem po jakimś dochodzeniu, postanowiłem odkomentuj te linie kodu w jego AnimatedExpandListView:

 if (lastGroup && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
      return expandGroup(groupPos, true); 
     } 

który spowodował problem (moja aplikacja jest przeznaczony dla systemu Android 4.0+).

+1

Aby rozwinąć ostatnią grupę z animacją, musiałem zmienić "> =" dla "<". – KunamiPT

Powiązane problemy