5.11. ListView

5.11. ListView

ListView – виджет для показа списка элементов. Можно использовать во всех приложениях, где используются списки. Для показа информации посредством ListView необходим класс производный от класса адаптера, в данном примере используется класс производный от BaseAdapter.

Создайте проект с использованием макета Empty Activity. Нажмите правой кнопкой мыши на папку res/layout и выберите New -> Layout Resource File. Назовите файл adapter_item.xml и укажите в качестве Root Element значение LinearLayout, затем в файле adapter_item.xml напишите следующий код:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@mipmap/ic_launcher"
        android:drawablePadding="12dp"
        android:gravity="center_vertical"
        android:text="Sample"
        android:textColor="@color/colorPrimary"
        android:textSize="18sp" />
</LinearLayout>

В файле activity_main.xml напишите:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity"
    android:orientation="vertical">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/list"/>
</LinearLayout>

Добавьте новый класс (в предыдущих уроках было сказано как). Назовите класс SampleListAdapter в поле Superclass напишите BaseAdapter и в коде класса напишите:

// Класс предоставляющий возможность определения поведения адаптера для правильной привязки информации к виджетам
public class SampleListAdapter extends BaseAdapter {
    // Объявление необходимых перенных получаемых через конструктор.
    // Объект Context необходим для получения ссылки на Activity в котором адаптер подключается к ListView.
    Context context;
    // Массив для хранения элементов для привязки к ListView
    List<String> items = new ArrayList<>();

    // Конструктор класса адаптера, принимает параметры контекста и элементов переданных с Activity
    public SampleListAdapter(Context context, List<String> items)
    {
        // Присвоить полученные параметры локальным переменным класса
        this.context = context;
        this.items = items;
    }

    // Функция для возвращения количества элементов
    @Override
    public int getCount() {
        return items.size();
    }

    // Получить элемент для показа в необходимой позиции
    @Override
    public String getItem(int position) {
        return items.get(position);
    }

    // Получить id элемента, обычно возвращается запрашиваемое значение переданное по параметру, потому что в массиве расположение элементов идёт по порядку и так и показывается в ListView на данный момент.
    @Override
    public long getItemId(int position) {
        return position;
    }

    // Получить корневой View, в котором и распологаются виджеты
    @Override
    public View getView(int position, View view, ViewGroup parent) {
        // Если View ещё не создавался создать
        // иначе использовать уже созданный ранее view
        if(view == null)
        {
            // Получить ссылку к экземпляру LayoutInflater для получения xml файла макета
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            // Запросить файл макета и присвоить переменной view класса View теперь view это LinearLayout объявленный в файле adapter_item.xml
            // В файле adapter_item.xml определяется макет для одной строки списка, потому что структура всех строк списка одинаковая
            view = inflater.inflate(R.layout.adapter_item, parent, false);
        }
        // Найти ссылку на TextView внутри LinearLayout файла макета
        TextView text = view.findViewById(R.id.text);
        // Установить значение для TextView равной значению элемента массива соответствующей позиции данной строки
        text.setText(items.get(position));
        // Установить в качестве тега TextView значение позиции элемента тег может хранить в себе объект и служит для дальнейшего определения этого объекта по тегу или хранения и обработки информации, которую нет нужды показывать в интерфейсе пользователю
        text.setTag(position);
        // Вернуть объект View - корневой LinearLayout из файла adapter_item.xml
        return view;
    }
}

В файле MainActivity.java напишите этот код:

public class MainActivity extends AppCompatActivity {
    // Виджет для показа списка
    ListView listView;
    // Массив для хранения заголовков
    List<String> items = new ArrayList<>(Arrays.asList("Тоҷикистон", "Ӯзбекистон", "Қирғизистон", "Қазоқистон"));

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Получение экземпляра ListView размещенного в макете
        listView = findViewById(R.id.list);

        // Объявление и инициализация экземпляра адаптера класса SimpleListAdapter адаптер служит для соединения данных с виджетом для показа
        SampleListAdapter adapter = new SampleListAdapter(this, items);
        // привязать адаптер к ListView
        listView.setAdapter(adapter);
        // Указать обработчик кликов по элементам списка
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            // Каждый раз при клике на какой-либо элемент вызывается функция onItemClick и ей передаётся в качестве параметра корневой элемент макета, в данном случае LinearLayout позиция выбранного элемента и id элемента. Через корневой элемент макета переданного через экземпляр класса View можно получить ссылку к любому объекту в макете. Например, через их id.
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // Получить ссылку на TextView в файле макета по id
                TextView textView = view.findViewById(R.id.text);
          // Показать сообщение с текстом TextView  из файла макета
          Toast.makeText(MainActivity.this, textView.getText(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}
Так держать, протестируйте приложение и двигайтесь дальше.