Próbuję ustalić najlepszy sposób, aby mieć pojedynczy ListView, który zawiera różne układy dla każdego wiersza. Wiem, jak utworzyć niestandardowy wiersz + niestandardowy adapter tablicy, aby obsługiwał niestandardowy wiersz dla całego widoku listy, ale jak mogę wdrożyć wiele różnych stylów wierszy w widoku listy?
android
listview
listviewitem
w.donahue
źródło
źródło
Odpowiedzi:
Ponieważ wiesz, ile rodzajów układów miałbyś - możesz skorzystać z tych metod.
getViewTypeCount()
- ta metoda zwraca informację, ile rodzajów wierszy masz na liściegetItemViewType(int position)
- zwraca informację, jakiego typu układu należy użyć na podstawie pozycjiNastępnie nadmuchujesz układ tylko wtedy, gdy jest on pusty i określasz typ za pomocą
getItemViewType
.Więcej informacji znajdziesz w tym samouczku .
Aby osiągnąć pewne optymalizacje w strukturze, które opisałeś w komentarzu, sugerowałbym:
ViewHolder
. Zwiększy to prędkość, ponieważ nie będziesz musiał wywoływać zafindViewById()
każdym razemgetView
metody. Zobacz List14 w prezentacjach API .Mam nadzieję, że ci to pomoże. Jeśli możesz podać kod XML ze swoją strukturą danych i informacjami, w jaki sposób chcesz zamapować go w wierszu, byłbym w stanie udzielić Ci dokładniejszych porad. Po pikselach.
źródło
Znasz już podstawy. Wystarczy, że niestandardowy adapter zwróci inny układ / widok na podstawie dostarczonych informacji o wierszu / kursorze.
A
ListView
może obsługiwać wiele stylów wierszy, ponieważ pochodzi z AdapterView :Jeśli spojrzysz na adapter , zobaczysz metody uwzględniające użycie widoków specyficznych dla wierszy:
Dwie ostatnie metody zapewniają położenie, dzięki czemu można użyć tego do określenia typu widoku, którego należy użyć dla tego wiersza .
Oczywiście na ogół nie używasz bezpośrednio AdapterView i Adapter, ale raczej używasz lub wywodzi się z jednej z ich podklas. Podklasy adaptera mogą dodawać dodatkowe funkcje, które zmieniają sposób uzyskiwania niestandardowych układów dla różnych wierszy. Ponieważ widok używany dla danego wiersza jest sterowany przez adapter, sztuczka polega na tym, aby adapter zwrócił żądany widok dla danego wiersza. Jak to zrobić, różni się w zależności od konkretnego adaptera.
Na przykład, aby użyć ArrayAdapter ,
getView()
aby napompować, wypełnić i przywrócić żądany widok dla danej pozycji.getView()
Metoda obejmuje możliwość ponownego wykorzystania poglądów za pośrednictwemconvertView
parametru.Ale aby użyć pochodnych CursorAdapter ,
newView()
aby napompować, wypełnić i przywrócić żądany widok dla bieżącego stanu kursora (tj. bieżący „wiersz”) [należy również przesłonićbindView
, aby widżet mógł ponownie wykorzystywać widoki]Aby jednak użyć SimpleCursorAdapter ,
SimpleCursorAdapter.ViewBinder
za pomocąsetViewValue()
metody nadmuchiwania, wypełniania i zwracania pożądanego widoku dla danego wiersza (aktualny stan kursora) i „kolumny” danych. Metoda może zdefiniować tylko „specjalne” widoki i odroczyć standardowe zachowanie SimpleCursorAdapter dla „normalnych” powiązań.Poszukaj konkretnych przykładów / samouczków dotyczących rodzaju używanego adaptera.
źródło
BaseAdapter
. Pochodzenie z BaseAdapter byłoby najbardziej „elastyczne”, ale najgorzej byłoby w przypadku ponownego wykorzystania kodu i dojrzałości, ponieważ nie wykorzystuje on wiedzy i dojrzałości już wprowadzonych w innych adapterach.BaseAdapter
jest dostępny w niestandardowych kontekstach, w których inne adaptery nie pasują.CursorAdapter
iSimpleCursorAdapter
.ArrayAdapter
, nie ma znaczenia, jaki układ dajesz konstruktorowi, o ilegetView()
nadmuchuje i zwraca odpowiedni typ układugetViewTypeCount()
jest uruchamiany tylko raz za każdym razem, gdy dzwoniszListView.setAdapter()
, a nie za każdym razemAdapter.notifyDataSetChanged()
.Spójrz w poniższy kod.
Najpierw tworzymy niestandardowe układy. W tym przypadku cztery typy.
even.xml
odd.xml
white.xml
black.xml
Następnie tworzymy element widoku listy. W naszym przypadku ze sznurkiem i typem.
Następnie tworzymy uchwyt widoku. Jest to zdecydowanie zalecane, ponieważ system operacyjny Android zachowuje odniesienie do układu, aby ponownie użyć elementu, gdy zniknie i pojawi się z powrotem na ekranie. Jeśli nie zastosujesz tego podejścia, za każdym razem, gdy element pojawi się na ekranie, system operacyjny Android utworzy nowy i spowoduje wyciek pamięci z aplikacji.
Na koniec tworzymy nasz niestandardowy adapter nadpisujący getViewTypeCount () i getItemViewType (pozycja int).
Nasza działalność jest mniej więcej taka:
teraz utwórz widok listy w mainactivity.xml w ten sposób
źródło
W niestandardowym adapterze tablicowym zastępujesz metodę getView (), jak zapewne znasz. Następnie wystarczy użyć instrukcji switch lub instrukcji if, aby zwrócić określony widok niestandardowy w zależności od argumentu position przekazanego do metody getView. Android jest sprytny, ponieważ daje ci tylko widok konwersji odpowiedniego typu dla twojej pozycji / wiersza; nie musisz sprawdzać, czy jest poprawnego typu. Możesz w tym pomóc Androidowi, odpowiednio nadpisując metody getItemViewType () i getViewTypeCount ().
źródło
Jeśli musimy pokazać inny typ widoku w widoku listy, dobrze jest użyć getViewTypeCount () i getItemViewType () w adapterze zamiast przełączania widoku VIEW.GONE i VIEW.VISIBLE może być bardzo kosztownym zadaniem w getView (), które będzie wpływa na przewijanie listy.
Sprawdź to, aby użyć getViewTypeCount () i getItemViewType () w adapterze.
Link: the-use-of-getviewtypecount
źródło
ListView był przeznaczony do prostych przypadków użycia, takich jak ten sam widok statyczny dla wszystkich elementów wiersza.
Ponieważ musisz tworzyć ViewHolders i w znacznym stopniu wykorzystywać
getItemViewType()
i dynamicznie wyświetlać różne pliki XML układu elementów wiersza, powinieneś spróbować to zrobić za pomocą RecyclerView , który jest dostępny w Android API 22. Oferuje lepszą obsługę i strukturę dla wielu typów widoków.Sprawdź ten samouczek na temat korzystania z RecyclerView do robienia tego, czego szukasz.
źródło