После привязки ListView к источнику данных через адаптер мы можем работать с данными - добавлять, удалять, изменять только через адаптер. ListView служит только для отображения данных.
Для управления данными мы можем использовать методы адаптера или напрямую источника данных. Например, класс ArrayAdapter предоставляет следующие методы для управления данными:
void add(T object): добавляет элемент object в конец массива
void addAll(T... items): добавляет все элементы items в конец массива
void addAll(Collection<? extends T> collection): добавляет коллекцию элементов collection в конец массива
void clear(): удаляет все элементы из списка
void insert(T object, int index): добавляет элемент object в массив по индексу index
void remove(T object): удаляет элемент object из массива
Однако после применения вышеуказанных методов изменения коснутся только массива, выступающего источником данных. Чтобы синхронизировать изменения
с элементом ListView
, надо вызвать у адаптера метод notifyDataSetChanged()
.
Например, определим в файле activity_main.xml следующие элементы:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/userName" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintHorizontal_weight="4" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/add" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/add" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintHorizontal_weight="1" android:text="+" android:onClick="add" app:layout_constraintRight_toLeftOf="@+id/remove" app:layout_constraintLeft_toRightOf="@+id/userName" app:layout_constraintTop_toTopOf="parent"/> <Button android:id="@+id/remove" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintHorizontal_weight="1" android:text="-" android:onClick="remove" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toRightOf="@+id/add" app:layout_constraintRight_toRightOf="parent" /> <ListView android:id="@+id/usersList" android:layout_width="0dp" android:layout_height="0dp" android:choiceMode="multipleChoice" app:layout_constraintTop_toBottomOf="@+id/userName" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"> </ListView> </androidx.constraintlayout.widget.ConstraintLayout>
Для вывода списка предназначен ListView с возможностью множественного выбора элементов. Для добавления и удаления определены две кнопки. Для ввода нового объекта в список предназначено поле EditText.
Теперь изменим класс MainActivity:
package com.example.listapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import java.util.ArrayList; import java.util.Collections; public class MainActivity extends AppCompatActivity { ArrayList<String> users = new ArrayList<String>(); ArrayList<String> selectedUsers = new ArrayList<String>(); ArrayAdapter<String> adapter; ListView usersList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // добавляем начальные элементы Collections.addAll(users, "Tom", "Bob", "Sam", "Alice"); // получаем элемент ListView usersList = findViewById(R.id.usersList); // создаем адаптер adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_multiple_choice, users); // устанавливаем для списка адаптер usersList.setAdapter(adapter); // обработка установки и снятия отметки в списке usersList.setOnItemClickListener(new AdapterView.OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // получаем нажатый элемент String user = adapter.getItem(position); if(usersList.isItemChecked(position)) selectedUsers.add(user); else selectedUsers.remove(user); } }); } public void add(View view){ EditText userName = findViewById(R.id.userName); String user = userName.getText().toString(); if(!user.isEmpty()){ adapter.add(user); userName.setText(""); adapter.notifyDataSetChanged(); } } public void remove(View view){ // получаем и удаляем выделенные элементы for(int i=0; i< selectedUsers.size();i++){ adapter.remove(selectedUsers.get(i)); } // снимаем все ранее установленные отметки usersList.clearChoices(); // очищаем массив выбраных объектов selectedUsers.clear(); adapter.notifyDataSetChanged(); } }
С добавлением все относительно просто: получаем введенную строку и добавляем в список с помощью метода adapter.add(). Чтобы обновить ListView после добавления вызывается метод adapter.notifyDataSetChanged().
А для удаления создается дополнительный список selectedUsers, который будет содержать выделенные элементы. Для получения выделенных элементов и добавления
их в список используется слушатель AdapterView.OnItemClickListener, метод onItemClick()
которого вызывается при установке или снятия отметки с элемента, то есть
при любом нажатии на элемент.
По нажатию на кнопку удаления пробегаемся по списку выделенных элементов и вызываем для каждого из них метод adapter.remove().