Ciekawi mnie przeznaczenie metod getItem
i getItemId
klasy Adapter w Android SDK.
Z opisu wynika, że getItem
powinno zwrócić podstawowe dane. Tak więc, jeśli mam tablicę imion ["cat","dog","red"]
i utworzę adapter a
za pomocą tego, to a.getItem(1)
powinienem zwrócić „pies”, prawda? Co powinno a.getItemId(1)
wrócić?
Jeśli korzystałeś z tych metod w praktyce, czy możesz podać przykład?
getItemId()
wArrayAdapter()
zawsze wraca-1
zassert false : "TODO"; return -1;
Odpowiedzi:
Postrzegam te metody jako czystsze podejście do uzyskiwania dostępu do danych mojej listy. Zamiast bezpośredniego dostępu do mojego obiektu adaptera za pośrednictwem czegoś takiego,
myListData.get(position)
mogę po prostu wywołać adapter w styluadapter.get(position)
.To samo dotyczy
getItemId
. Zwykle używałbym tej metody, gdy chcę wykonać jakieś zadanie na podstawie unikalnego identyfikatora obiektu na liście. Jest to szczególnie przydatne podczas pracy z bazą danych. Zwróconyid
może być odniesieniem do obiektu w bazie danych, na którym mógłbym następnie wykonać różne operacje (aktualizacja / usunięcie / itp.).Zamiast więc uzyskiwać dostęp do identyfikatora z surowego obiektu danych, jak
myListData.get(position).getId()
możesz użyćadapter.getItemId(position)
.Jednym z przykładów, w którym czułem, że muszę użyć tych metod, był projekt korzystający z SeparatedListViewAdapter . Ten adapter może zawierać wiele różnych rodzajów adapterów, z których każdy reprezentuje dane innego typu (zazwyczaj). Dzwoniąc
getItem(position)
naSeparatedListViewAdapter
, obiekt zwrócony może być różny w zależności od „sekcja” sytuacja jest taka, że ty ją wysłać.Na przykład, gdybyś miał 2 sekcje na swojej liście (owoce i cukierki): Jeśli użyłeś
getItem(position)
i przypadkowo znalazłeśposition
się na pozycji w sekcji owoców , otrzymasz inny przedmiot niż gdybyś poprosiłgetItem(position)
oposition
wskazanie przedmiotu w cukierku Sekcja. Możesz wtedy zwrócić jakąś stałą wartość identyfikatora,getItemId(position)
która reprezentuje rodzaj zwracanych danychgetItem(position)
, lub użyć jejinstanceof
do określenia posiadanego obiektu.Poza tym, o czym wspomniałem, nigdy nie czułem, że naprawdę potrzebuję tych metod
źródło
getView
,getCount
,getViewTypeCount
Itp są wykorzystywane specjalnie dla prawidłowo pokazując swoją listview UI. inne funkcje po prostu pomagają w tworzeniu implementacji innych funkcjonalności, takich jak wykonywanie dalszych czynności po kliknięciu elementu itp., chociaż często używamgetItem
wewnątrzgetView
getItemId
, po prostu zwróć0L
lubnull
nigdzie nie używaj. Nie widzę żadnego oczywistego powodu, dla którego UUID miałby być cenniejszy niż tylko jakaślong
wartość identyfikatora. Tryb rozłączony? Co to jest?Cóż, wydaje się, że na to pytanie można odpowiedzieć w prostszy i bardziej bezpośredni sposób ... :-)
Mówiąc najprościej, Android umożliwia dołączenie
long
do dowolnegoListView
elementu, to takie proste. Gdy system powiadomi Cię o wyborze użytkownika, otrzymasz trzy zmienne identyfikujące, aby poinformować Cię, co zostało wybrane:long
dołączyłeś do poszczególnych elementów.Do Ciebie należy decyzja, który z tych trzech elementów jest dla Ciebie najłatwiejszy w Twoim konkretnym przypadku, ale cały czas masz do wyboru wszystkie trzy. Pomyśl o tym
long
jak o tagu automatycznie dołączonym do przedmiotu, tyle że jest jeszcze prostszy i łatwiejszy do odczytania.Nieporozumienie co do tego, co zwykle robi, wynika z prostej konwencji. Wszystkie adaptery muszą zapewniać
getItemId()
nawet, jeśli w rzeczywistości nie używają tej trzeciej identyfikacji. Tak więc, zgodnie z konwencją, te adaptery (w tym wiele w przykładach w SDK lub w całej sieci) po prostu wracająposition
z jednego powodu: są zawsze unikalne. Mimo to, jeśli adapter powróciposition
, to naprawdę oznacza, że nie chce w ogóle korzystać z tej funkcji, ponieważ i takposition
jest już znana.Jeśli więc chcesz zwrócić inną wartość, którą uważasz za stosowną, możesz to zrobić:
źródło
getItemId()
… Co się stanie, gdy / jeśli ta metoda nie zostanie zastąpiona w niestandardowym adapterze?Plik
getItemId
Metoda jest w dużej mierze przeznaczony do pracy z kursory, które są wspierane przez bazami danych SQLite. Zwróci pole id kursora bazowego dla elementu na pozycji 1.W twoim przypadku nie ma identyfikatora dla elementu na pozycji 1: zakładam, że implementacja ArrayAdapter po prostu zwraca -1 lub 0.
EDYCJA: właściwie zwraca tylko pozycję: w tym przypadku
1
.źródło
-1
. Oto realizacjaassert false : "TODO"; return -1;
Chciałbym wspomnieć, że po wdrożeniu
getItem
igetItemId
możesz użyć ListView.getItemAtPosition i ListView.getItemIdAtPosition, aby uzyskać bezpośredni dostęp do danych, zamiast przechodzić przez adapter. Może to być szczególnie przydatne podczas implementowania nasłuchiwania onClick.źródło
Jeśli zaimplementujesz
getItemId
poprawnie, może to być bardzo przydatne.Przykład:
Masz listę albumów:
I wdrażasz w
getItemId
ten sposób:Teraz twój identyfikator pozycji zależy od wartości pól coverUrl i title, a jeśli zmienisz to i wywołasz
notifyDataSetChanged()
adapter, adapter wywoła metodę getItemId () każdego elementu i zaktualizuje tylko te elementy, których id zmienił się.Jest to bardzo przydatne, jeśli wykonujesz jakieś „ciężkie” operacje w swoim
getView()
.BTW: jeśli chcesz, żeby to zadziałało, musisz upewnić się, że twoja
hasStableIds()
metoda zwraca false;źródło
hasStableIds()
zwrócić fałsz? Wydaje mi się, że hashcode obliczony z tego samego ciągu zwracałby za każdym razem tę samą wartość, która jest stabilnym identyfikatorem zgodnie z dokumentacją .getItem
lubgetItemId
jest kilka metod przeznaczonych głównie do załączania danych z pozycjami na liście. W przypadkugetItem
, możesz przekazać dowolny obiekt, który zostanie dołączony do pozycji na liście. Zwykle ludzie wracająnull
.getItemId
to dowolna unikalnalong
wartość, którą można dołączyć do tego samego elementu na liście. Ludzie zazwyczaj zwracają pozycję na liście.Jakie jest zastosowanie. Ponieważ te wartości są powiązane z elementem na liście, możesz je wyodrębnić, gdy użytkownik kliknie element. Te wartości są dostępne za pomocą
AdapterView
metod.źródło