2010-04-04 13 views
5

Mam następujący problem:wyboru „sprawdzone” w ListView jest przywracany po przewinięciu

Mam ListActivity jego ListView składa się ikoną, tekstu i wyboru (przy LayoutInflater).

Adapter dla ListView rozciąga ResourceCursorAdapter (czyli źródło danych ListView są pobierane z bazy danych, również sprawdzone status każdego rzędu)

wszystko działa całkiem ok, z wyjątkiem kiedy odznacz/zaznacz pole wyboru w dowolnym wierszu, jeśli przewijam w dół, dopóki zmodyfikowane pole wyboru nie będzie już widoczne, a następnie przewiń w górę, pole wyboru zostanie przywrócone do pierwotnego stanu.

Baza danych została zmodyfikowana, to nie jest problem (tj. Jeśli zmodyfikuję wiersz i zakończę działanie, i ponownie wprowadzam, zmodyfikowany wiersz jest wyświetlany Ok).

Domyślam się, że ma to jakiś związek z wyliczaniem listy, ponieważ z jakiegoś powodu ListView "renderuje" oryginalny stan wszystkich wierszy, kiedy został zapełniony podczas przewijania.

Szukałem tego błędu, ale nie znalazłem nikogo, kto miałby ten problem. Doceniam każdą twoją radę.

Odpowiedz

1

Problem został rozwiązany przez zamknięcie odpowiedniego kursora po zmodyfikowaniu bazy danych i ponowne otwarcie jej za pomocą changeCursor().

+0

czy możesz mi powiedzieć, gdzie napisać to ponowne otwarcie kodu kursora? mam na myśli bindwe, newview czy gdzieś indziej? – Hunt

1

Gdy element zostanie wyświetlony, zostanie wywołana twoja metoda ListAdapter.getView().

Może się to zdarzyć wiele razy na sesję, jeśli na przykład przewiniesz element poza ekranem i włączysz go ponownie.

Proponuję umieścić punkt przerwania na getView() i uruchomić aplikację z debugerem. Powtórz test, a przy okazji po raz drugi wywołaj metodę getView(), sprawdź logikę, w której ustawione jest twoje pole wyboru.

Kolejnym czynnikiem jest to, że drugi parametr getView to widok "convertView". To jest jedno z twoich widoków z innych wpisów listy, które nie są już widoczne. System operacyjny zwraca ten widok użytkownikowi, aby umożliwić mu "przetworzenie" widoku w celu utworzenia nowego wpisu, zamiast nadmuchiwania nowego, który będzie miał wpływ na wydajność.

Jeśli zignorujesz ten parametr, nie będzie to stanowić problemu (chociaż aby utworzyć płynną przewijaną listę, możesz rozważyć użycie jej w przyszłości - pamiętaj tylko, aby sprawdzić, czy Widok jest tego typu, jakiego oczekujesz, ustawiając Etykietka).

Jeśli zdecydujesz się użyć tego parametru do próby odtworzenia widoku, sprawdź logikę i upewnij się, że ustawiasz wszystkie kontrolki do żądanego stanu, ponieważ stan domyślny układu może nie mieć zastosowania.

+0

Dzięki za odpowiedź. Jak rozumiem, dla CursorAdapter I powinien zmodyfikować zawartość widoku w metodzie bindView. Nie jestem pewien, czy w tym przypadku używa się getView. Lub w każdym przypadku, kiedy bindView zostanie wywołany i kiedy getView? W tej chwili nie używam wcale getView, tylko newView i bindView. Nauczyłem się trochę o getView i korzystaniu z convertView do recyklingu widoku, ale wciąż jestem zdezorientowany, kiedy zostanie wywołany bindView (getView i bindView będą miały ten sam kod?) Ponadto, bindView nie przekazuje convertView, ale tylko widok. – adrianrdzv

2

Ten link daje wgląd problemu

EditText items in a scrolling list lose their changes when scrolled off the screen

Lista wierszy się recyklingowi. Twój kursor może mieć 1000 rekordów, ale nie będzie 1000 widżetów EditText utworzonych podczas przewijania listy przez . Zamiast tego będzie 10 lub , więc w zależności od tego, ile wierszy jest jednocześnie wyświetlanych .Wiersze uzyskać recyklingowi, a operacja wiążąca zastąpi starą wartość EditText z nową wartość z kursorem na cokolwiek rząd po prostu przewijane na ekranie , zastępując cokolwiek tam przed (poprzedniej wartości z bazy danych lub wartość edytowana przez użytkownika).

Powiązane problemy