ПРОГРАММИРОВАНИЕ НА ANDROID STUDIO — CUSTOM SPINNER (НАСТРАИВАЕМЫЙ ВЫПАДАЮЩИЙ СПИСОК) Ч. 2.2
В нашем сегодняшнем уроке мы продолжим рассматривать возможности настраиваемого выпадающего списка (Custom Spinner) в Android Studio.
Давайте предположим, что нам необходимо сделать выпадающий список таким образом, чтобы в случаи, когда список развёрнут, то каждый пункт списка отображал бы полную информацию, а в случаи, когда какой-то пункт выбран, то отображалась бы краткая информация. Создайте новое приложение в Android Studio с пустым активити (Empty Activity), и начнём делать наш список. Список будет содержать автомобильные бренды, логотипы этих брендов и информацию о сайте производителя. Пусть в развёрнутом виде нам нужно отображать логотип, наименование бренда и ссылку на сайт, а когда пункт выбран, только логотип и наименование бренда. Создадим шаблон пункта выпадающего списка. Для этого перейдите к каталогу layout ресурсов проекта:
Нажмите на этом каталоге правой кнопкой мыши и в появившемся меню выберите New -> Layout resource file: Назовите его spinner_item: Отредактируйте содержимое spinner_item.xml в соответствии со следующим текстом:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginBottom="10dp"> <ImageView android:id="@+id/ivBrandLogo" android:layout_gravity="center_horizontal|center_vertical" android:layout_width="70dp" android:layout_height="50dp" android:layout_marginLeft="10dp"/> <TextView android:id="@+id/tvBrandName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="left|center_vertical" android:textSize="20sp" android:textStyle="bold"/> </LinearLayout> <TextView android:id="@+id/tvOfficialSite" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|center_vertical" android:layout_marginLeft="80dp" android:textSize="15sp" android:textStyle="italic"/> </LinearLayout> </LinearLayout>
В той же папке layout, где был создан spinner_item.xml аналогичным образом создайте шаблон для выбранного пункта списка и назовите его selected_item.xml. Отредактируйте содержимое selected_item.xml в соответствии со следующим текстом:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginBottom="10dp"> <ImageView android:id="@+id/ivBrandLogo" android:layout_gravity="center_horizontal|center_vertical" android:layout_width="70dp" android:layout_height="50dp" android:layout_marginLeft="10dp"/> <TextView android:id="@+id/tvBrandName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="left|center_vertical" android:textSize="20sp" android:textStyle="bold"/> </LinearLayout> </LinearLayout>
Теперь перейдите к файлу activity_main.xml, который расположен в том же каталоге layout и добавьте туда элемент Spinner. Должно получиться следующее:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ru.lessons.customspinnerlesson.MainActivity"> <Spinner android:id="@+id/spAutoBrands" android:layout_width="fill_parent" android:layout_height="wrap_content"></Spinner> </android.support.constraint.ConstraintLayout>
После всего этого нам нужно создать класс, который будет содержать в себе информацию о каждом отдельно взятом бренде, т.е. наименование бренда, информацию о сайте и логотип. Для этого перейдём к каталогу, в котором у нас расположен MainActivity и создадим в нём подкаталог, к котором разместим наш класс: Нажмём на нём правой кнопкой мыши. В появившемся меню выберем New -> Package: Назовите новый каталог AdditionalClasses: Нажмите на вновь созданный каталог AdditionalClasses правой кнопкой мыши и выберите New -> Java Class: Назовите новый класс AutoBrandClass:
Отредактируйте его код в соответствии со следующим текстом:
package ru.lessons.customspinnerlesson.AdditionalClasses; public class AutoBrandClass { private String brandName; //Наименование бренда private String officialSite; //Официальный сайт private int brandLogo; //Логотип public AutoBrandClass(String brandName, String officialSite, int brandLogo) { this.brandName = brandName; this.officialSite = officialSite; this.brandLogo = brandLogo; } public String getBrandName() { return brandName; } public String getOfficialSite() { return officialSite; } public int getBrandLogo() { return brandLogo; } }
В том же каталоге, где был создан каталог AdditionalClasses создайте ещё один каталог и назовите его Adapters. Должно получиться так: Теперь создадим адаптер для выпадающего списка. Нажмите на каталоге Adapters правой кнопкой мыши и выберите New -> Java Class (Все действия аналогичны тем, которые мы делали при создании класса AutoBrandClass). Назовите этот класс AutoBrandsSpinnerAdapter. Отредактируйте его код в соответствии со следующим текстом: Теперь нам понадобятся три графических png файла, который будут содержать логотипы брендов — toyota.png, nissan.png и bmw.png. Их нужно просто скопировать в каталог drawable проекта:
Взять архив с логотипами можно здесь: LogoImg
Теперь перейдите к MainActivity и отредактируйте его в соответствии со следующим кодом:
package ru.lessons.customspinnerlesson.Adapters; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import ru.lessons.customspinnerlesson.AdditionalClasses.AutoBrandClass; import ru.lessons.customspinnerlesson.R; public class AutoBrandsSpinnerAdapter extends BaseAdapter { private LayoutInflater layoutInflater; private ArrayList < AutoBrandClass > autoBrandsList; //Массив экземпляров класса AutoBrandClass, которые содержат //описание каждого отдельно взятого бренда public AutoBrandsSpinnerAdapter(Context context, ArrayList < AutoBrandClass > autoBrandsList) { //Содержимое autoBrandsList создаётся в коде MainActivity //и передаётся в конструктор адаптера при его создании this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.autoBrandsList = autoBrandsList; } @Override public int getCount() { return autoBrandsList.size(); //возвращает размер массива autoBrandsList } @Override public Object getItem(int position) { return autoBrandsList.get(position); //возвращает элемент массива autoBrandsList //по переданной в функцию позиции (индексу в массиве) } @Override public long getItemId(int position) { return 0; } //Этот метод отрисовывает выбранный пункт списка @Override public View getView(int position, View convertView, ViewGroup parent) { View view = layoutInflater.inflate(R.layout.selected_item, parent, false); //получает текущий элемент массива autoBrandsList AutoBrandClass autoBrand = (AutoBrandClass) getItem(position); //находим TextView, предназначенный для отображения наименования бренда //и устанавливаем текст TextView tvBrandName = (TextView) view.findViewById(R.id.tvBrandName); tvBrandName.setText(autoBrand.getBrandName()); //Находим ImageView, предназначенный для отображения логотипа //и устанавливаем картинку логотипа ImageView ivBrandLogo = (ImageView) view.findViewById(R.id.ivBrandLogo); ivBrandLogo.setImageResource(autoBrand.getBrandLogo()); return view; } //Этот метод отрисовывает каждый пункт развёрнутого списка @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { View view = layoutInflater.inflate(R.layout.spinner_item, parent, false); //получает текущий элемент массива autoBrandsList AutoBrandClass autoBrand = (AutoBrandClass) getItem(position); //находим TextView, предназначенный для отображения наименования бренда //и устанавливаем текст TextView tvBrandName = (TextView) view.findViewById(R.id.tvBrandName); tvBrandName.setText(autoBrand.getBrandName()); //находим TextView, предназначенный для отображения официального сайта //и устанавливаем текст TextView tvOfficialSite = (TextView) view.findViewById(R.id.tvOfficialSite); tvOfficialSite.setText(autoBrand.getOfficialSite()); //Находим ImageView, предназначенный для отображения логотипа //и устанавливаем картинку логотипа ImageView ivBrandLogo = (ImageView) view.findViewById(R.id.ivBrandLogo); ivBrandLogo.setImageResource(autoBrand.getBrandLogo()); return view; } }