Android SimpleAdapter

Конструкторът на класаSimpleAdapterизглежда така:

За данните в параметъраdataсе използва колекция от обекти Map или негови наследници, напримерHashMap. ВсякаКартасъдържа данни за отделен елемент от списъка. За да може адаптерът да разбере какви данни трябва да бъдат вмъкнати в компонентите на изгледа на всеки елемент от списъка, ние определяме два масиваотидо. В масиваfromизползваме ключовете отMap, а в масиваtoизползваме идентификаторите на компонентите. Адаптерът последователно итерира всички компоненти от масиваtoи ги съпоставя със съответните стойности отfrom. Уверете се, че в масиваtoняма повече елементи, отколкото вfrom, в противен случай програмата ще изведе грешка.

Използване на системно маркиране

Когато работихме с ArrayAdapter заListView, използвахме готовата маркировкаandroid.R.layout.simple_list_item_1, която се състои от един единственTextView. Има друго системно оформлениеandroid.R.layout.simple_list_item_2, състоящо се от два текстови етикета с идентификаториandroid.R.id.text1иandroid.R.id.text2, разположени на два реда. Първият етикет показва текста с голям шрифт, а вторият етикет го показва с малък шрифт.

Ако желаете, беше възможно да се наследи отArrayAdapterи да се приложи работа с такова маркиране. НоSimpleAdapterвече е оптимизиран за този случай, така че можем да го използваме веднага.

тогава

Използвайки нашата собствена маркировка

Нека създадем отделна маркировка за всеки елемент от списъка:

Кодът за свързване на адаптера към списъка:

Резултатът ще бъде следният:

simpleadapter

Промените са минимални. Добавихме сериен номерMemberIDза всяка котка и в адаптерапосочиха не системата, а собствената си маркировкаR.layout.list_item. Използваме и масив от три елемента.

ListAdapter

В примерите по-горе можете спокойно да заменитеSimpleAdapterсListAdapter:

Това е само в случай, че не се страхувате, ако попаднете на такъв код.

Комплексно маркиране

Маркирането може да бъде всичко и да включва не само текстови етикети, но и други компоненти катоImageViewиCheckBox. Принципът остава същият. Създаваме ново маркиране и свързваме данни към всеки компонент.

Нека създадем нова маркировка (или редактирайте файлаlist_item.xmlот предишния пример)

Да видим какви са разликите. Сега използваме не само низове за имена на котки, но и булева стойност за квадратчето за отметка и цяло число за иконата. Следователно изразътHashMapще бъде заменен с по-универсаленHashMap

Нека да видим резултата. Познавам само една котка, която слуша и яде. Затова ще го маркираме като захранван по подразбиране.

android

Създадохме два масива, които ще се използват за съпоставяне на данни и компоненти. Масивътfromсъдържа имената на ключовете на картата, а масивътtoсъдържа идентификаторите на компонентите. Така първиятTextViewс идентификаторR.id.textview_nameще бъде вмъкнат с първата стойност на ключCatNameи т.н. Същото важи и за другите компонентиCheckBoxиImageView.

Адаптерът обхожда всички компоненти в масиваtoза всеки елемент от списъка и ги съпоставя със стойностите в масиваfrom. Оказва се тази таблица:

R.id.R.id.textview_name - Map.get("CatName") R.id.checkbox_feed - Map.get("IsHungry") R.id.imageview_cat - Map.get("Icon")

Тук възникваинтересен въпрос, но как адаптерът разбира кой метод да извика компонента, за да му предаде стойност. Например за компонентаCheckBoxтрябва да поставим отметка или да премахнем отметката от квадратчето, а не да показваме текст, както заTextView.

Вече се погрижихме за нас. Адаптерът гледа с какво си има работа и в зависимост от вида на компонента взема решение. Има няколко варианта, само три.

Първата опция - ако компонентът еTextViewили негов наследник, тогава текстът се вмъква. С други думи, извиква се методътSimpleAdapter.setViewText(), който извикваTextView.setText()и предава желаната стойност отMapтам.

Втората опция е, ако компонентът наследи интерфейсаCheckable, тогава адаптерът проверява дали съответната стойност отMapе от типboolean. Ако това е вярно, тогава се извиква методътCheckable.setChecked. Ако стойността не е от типboolean, тогава се проверява дали компонентът е дъщерен наTextView. Ако отговорът е да, тогава се вмъква текстовата стойност отКарта. В противен случай ще получим грешка. Интерфейсните компоненти наCheckableвключватCheckBox, CheckedTextView, CompoundButton, RadioButton, Switch, ToggleButton. Можете да видите сами. Нека заменим блокаCheckBoxсTextViewв маркиранетоlist_item.xml:

Нека да стартираме проекта и да видим следното:

simpleadapter

За щастие, приложението не се срива, то просто отпечатва стойностите на булевата променлива.

Третата опция - ако компонентът еImageViewили негов наследник, тогава се проверява типът данни. Ако типът може да бъде преобразуван в типInteger, тогава се извиква методътSimpleAdapter.setViewImage(ImageView v, int value),който извиква методаImageView.setImageResource(), т.е. ИД на ресурса от папкатаdrawableилиmipmapсе замества. Ако типът е различен, тогава се извиква методътSimpleAdapter.setViewImage (ImageView v, String value), който се опитва да прехвърли стойността къмintи да извика методаImageView.setImageResource(). Ако тази опция е неуспешна, тя преобразува низа в обектUriи извиква методаImageView.setImageURI(Uri).

Ако компонентът не съответства на нито един от трите типа, изброени по-горе, тогава ще получим грешка.

Нека продължим експериментите. Да кажем, че искаме да поставим отметка не само вCheckBox, но и в новия текст. Тъй като вече знаем, че потомците наTextViewмогат да показват текст, нека продължим по следния начин. Нека добавим нови елементи към нашитеfromиtoмасиви: