Wpis z mikrobloga

#java #android #adaptery

Mirki pomożecie? Mam problem z ListView.

Sprawa wygląda następująco:

- Po kliknięciu na element lisy, dany element zmienia stan (powiększa się itd).

- Adapter listy to własny adapter rozszerzający klasę Base Adapter.

Rozwiązałem to w tak:

- Po kliknięciu na element wywoływana jest metoda notifyDataSetChanged();

- Adapter na nowo przelatuje listę

- W metodzie getView() rozróżniam czy element został kliknięty i na podstawie tego decyduję czy pozostawić poprzedni stan czy zmienić parametry.

Sposób prosty i szybki, ale oczywiście jest problem. Bo gdy wywoływana jest metoda getView() i chce zwrócić poprzedni stan (poprzez return convertView) adapter czasami zwraca błędne View tzn inny element niż powinien być na danej pozycji. Dzieje się to tylko w momencie kiedy lista jest przesuwana.

Doszedłem do wniosku, że adapter niepoprawnie przechowuje elementy lisy. Zrobiłem więc tablicę View[] i w niej trzymam wszystkie elementy.

Rozwiązało to problem dublujących się elementów listy, ale teraz problemem jest co innego.

Metody onClick w danych elementach listy czasami nie działają. Nie widzę tu jakiejś prawidłowości. Po prostu wygląda to jak by było to losowe.

I w tym momencie opadają mi witki i robię typowe WTF. Obydwa rozwiązania nie działają prawidłowo i nie mam pomysłu jak to rozwiązać.

Mirkowe eksperty doradźcie bo walczę z tym od dłuższego czasu, a ani Google i StackOverflow pytane nie chcą konkretnie odpowiedzieć.
  • 7
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@siemanko: musiałbyś to rozbić na dwa osobne templaty, nadpisujesz wtedy getViewTypeCount() i getView(int position, View v, ViewGroup parent) w adapterze. Albo wewnątrz tego ifa gdzie zwracasz niezmieniony stan upewnić się, że ten niezmieniony jest poprawny (nie wiem co tam siedzi w initAnimations() ale może po prostu to tam wywołać, żeby ustawić poprawny wygląd wiersza). Ja u siebie w getView() robię takie coś:

LinkViewHolder holder = new LinkViewHolder();

if (v ==
  • Odpowiedz
@siemanko: no ta tablica z View działa pewnie podobnie, ale holder chyba mniej pamięci konsumuje. Spróbuj może zrobić to najbardziej topornie jak się da (za każdym razem na nowo tworzyć widok, aktualizować dane i podpinać eventy). Będzie to niezbyt wydajne ale wszystko powinno działać (w końcu zawsze wymuszasz podpięcie wszystkiego do aktualnie wyświetlanych elementów). Potem będziesz optymalizował, jak zadziała ;)

Tu też jest dobry tutorial.
  • Odpowiedz
@maciejkiner: Udało się! Tablica z Viewami działa ok. A co do listenerów to wystarczyło przy inicjacji każdego dać view.SetTag() i później go odczytywać. Przyznam, że dziwne to, ale pomogło.

Lars Vogel zawsze na propsie i trzeba będzie przerobić jego tutka bo widzę spore braki mam.

Muszę także przyjrzeć się tym holderom. Jeśli mówisz, że są bardziej wydajne to na pewno będzie przydatne. Dzięki za pomoc:)
  • Odpowiedz